"""B1 Mobile Reachability — echter Playwright-Scan auf iPhone-Emulation.

Ersetzt den statischen HTTP-Fetch im Backend-B1-Wiring durch eine
echte WebKit-Browser-Session mit `devices['iPhone 15']`-Preset. Misst:

  - hat Footer einen Reopen-Anchor (Text/aria-label/onclick)?
  - Tap-Target-Größe (boundingBox in px) — Apple HIG 44pt = ≥44 px
  - Click-Behavior: öffnet sich der CMP direkt? (DOM-Mutation +
    Modal-Detection nach 2s)

Output schema (für Backend-B1 ersetzbar mit statischer Logik):

  {
    "url": str,
    "has_anchor": bool,
    "anchor_text": str,
    "tap_target_px": {"w": int, "h": int} | None,
    "click_opens_cmp": bool,
    "modal_selector": str | None,
    "screenshot_b64": str (initial Footer-Crop),
    "engine_meta": {"engine": "webkit", "device": "iPhone 15",
                    "user_agent": str, "viewport": str},
  }
"""

from __future__ import annotations

import base64
import logging
from typing import Any

logger = logging.getLogger(__name__)

# Phrasen für Footer-Anchor-Suche (mirror des Backend-Service)
_REOPEN_PHRASES = (
    "cookie-einstellungen", "cookie einstellungen",
    "cookie-präferenzen", "cookie-praeferenzen",
    "cookie-einwilligung",
    "einwilligung verwalten",
    "consent manager", "consent settings", "consent-einstellungen",
    "datenschutz-einstellungen", "datenschutzeinstellungen",
    "cookies verwalten", "manage cookies", "manage preferences",
    "privacy settings", "privacy preferences",
    "tracking-einstellungen",
)


async def scan_mobile_reachability(url: str) -> dict[str, Any]:
    """Run Mobile-Safari emulation + footer reachability check."""
    try:
        from playwright.async_api import async_playwright
    except Exception as e:
        logger.warning("playwright not available: %s", e)
        return {"url": url, "error": "playwright missing"}

    async with async_playwright() as p:
        device_preset = p.devices.get("iPhone 15") or {}
        browser = await p.webkit.launch(headless=True)
        try:
            context = await browser.new_context(
                **device_preset,
                locale="de-DE",
                timezone_id="Europe/Berlin",
            )
            page = await context.new_page()
            try:
                await page.goto(url, wait_until="domcontentloaded",
                                timeout=30000)
            except Exception as e:
                return {"url": url, "error": f"goto failed: {e}"[:200]}
            try:
                await page.wait_for_timeout(1500)
            except Exception:
                pass

            ua = await page.evaluate("() => navigator.userAgent")
            viewport = page.viewport_size or {}
            engine_meta = {
                "engine": "webkit",
                "device": "iPhone 15",
                "user_agent": ua,
                "viewport": f"{viewport.get('width','?')}x{viewport.get('height','?')}",
            }

            # Find footer reopen anchor by text matching
            anchor_loc = None
            for phrase in _REOPEN_PHRASES:
                try:
                    candidate = page.locator(
                        f"footer >> text=/{phrase}/i"
                    ).first
                    if await candidate.count() > 0:
                        anchor_loc = candidate
                        anchor_text = phrase
                        break
                except Exception:
                    continue

            result: dict[str, Any] = {
                "url": url,
                "has_anchor": False,
                "anchor_text": "",
                "tap_target_px": None,
                "click_opens_cmp": False,
                "modal_selector": None,
                "engine_meta": engine_meta,
            }

            if anchor_loc is None:
                # Capture footer crop
                try:
                    footer = page.locator("footer").first
                    if await footer.count() > 0:
                        png = await footer.screenshot()
                        result["screenshot_b64"] = base64.b64encode(
                            png,
                        ).decode("ascii")[:120000]
                except Exception:
                    pass
                return result

            result["has_anchor"] = True
            result["anchor_text"] = anchor_text

            try:
                box = await anchor_loc.bounding_box()
                if box:
                    result["tap_target_px"] = {
                        "w": int(box["width"]), "h": int(box["height"]),
                    }
            except Exception:
                pass

            # DOM-Modal-Snapshot vorher
            try:
                before_modals = await page.evaluate(
                    "() => Array.from(document.querySelectorAll("
                    "'[role=dialog],[aria-modal=true],.cmp-modal,"
                    ".ot-sdk-container,#usercentrics-cmp')).length"
                )
            except Exception:
                before_modals = 0

            # Klick + warten
            try:
                await anchor_loc.click(timeout=5000)
                await page.wait_for_timeout(2000)
                after_modals = await page.evaluate(
                    "() => Array.from(document.querySelectorAll("
                    "'[role=dialog],[aria-modal=true],.cmp-modal,"
                    ".ot-sdk-container,#usercentrics-cmp')).length"
                )
                if after_modals > before_modals:
                    result["click_opens_cmp"] = True
                    result["modal_selector"] = (
                        "[role=dialog] | [aria-modal=true] | cmp-modal"
                    )
            except Exception as e:
                logger.info("anchor click skipped: %s", e)

            return result
        finally:
            await browser.close()
