"""Phase C — Banner scan + Cookie/DSE cross-check + TCF check + profile extract.

Covers (in the original `_run_compliance_check`):
  - Step 3b  Cookie-banner scan via consent-tester /scan (homepage,
             3-phase consent test)
  - Step 3c  Cross-check banner findings vs. cookie-policy text
  - Step 3d  TCF vendor vs. DSI cross-check + VVT entries
  - Step 4   Extract profile hints from documents
  - Step 4b  Determine scenario per document (skip / regenerate / fix /
             import)
  - Step 4c  Pad missing canonical doc_types so the report always shows
             every checklist row
"""

from __future__ import annotations

import logging

import httpx

from ._constants import CONSENT_TESTER_URL
from ._helpers import _pad_results_with_missing, _update

logger = logging.getLogger(__name__)


async def run_phase_c(state: dict) -> None:
    """Run banner scan + cross-checks + profile extraction. Mutates state."""
    check_id = state["check_id"]
    req = state["req"]
    doc_texts = state["doc_texts"]
    doc_entries = state["doc_entries"]
    results = state["results"]
    profile_dict = state["profile_dict"]

    # Step 3b: Banner-Check (automatic, uses first URL or homepage)
    banner_result = None
    banner_url = req.documents[0].url if req.documents and req.documents[0].url else ""
    # Use the homepage (strip path) for banner check
    if banner_url:
        from urllib.parse import urlparse
        parsed = urlparse(banner_url)
        banner_url = f"{parsed.scheme}://{parsed.netloc}"
    if banner_url:
        _update(check_id, "Cookie-Banner wird geprueft...", 82)
        try:
            async with httpx.AsyncClient(timeout=900.0) as client:  # P50: +10min for vendor-detail-phase
                resp = await client.post(
                    f"{CONSENT_TESTER_URL}/scan",
                    json={"url": banner_url, "timeout_per_phase": 10},
                )
                if resp.status_code == 200:
                    banner_result = resp.json()
        except Exception as e:
            logger.warning(
                "Banner check failed: %s (%s)", e or "<empty>", type(e).__name__,
            )

    # Step 3c: Cross-check Banner vs Cookie-Richtlinie (88-90%)
    if banner_result and "cookie" in doc_texts:
        from compliance.services.banner_cookie_cross_check import (
            cross_check_banner_vs_cookie,
        )
        from ..agent_doc_check_routes import CheckItem
        _update(check_id, "Banner vs. Cookie-Richtlinie abgleichen...", 89)
        cross_findings = cross_check_banner_vs_cookie(
            banner_result, doc_texts["cookie"],
        )
        if cross_findings:
            for r in results:
                if r.doc_type == "cookie":
                    for cf in cross_findings:
                        r.checks.append(CheckItem(**cf))
                    l2 = [c for c in r.checks if c.level == 2 and not c.skipped]
                    l2p = sum(1 for c in l2 if c.passed)
                    r.correctness_pct = round(l2p / len(l2) * 100) if l2 else 0

    # Step 3d: TCF Vendor cross-check against DSI
    tcf_vendors = banner_result.get("tcf_vendors", []) if banner_result else []
    vvt_entries: list[dict] = []
    if tcf_vendors and "dse" in doc_texts:
        _update(check_id, f"{len(tcf_vendors)} TCF-Verarbeiter vs. DSI abgleichen...", 91)
        from compliance.services.banner_cookie_cross_check import (
            cross_check_vendors_vs_dsi,
        )
        from compliance.services.vendor_vvt_mapper import map_vendors_to_vvt
        from ..agent_doc_check_routes import CheckItem
        vendor_findings = cross_check_vendors_vs_dsi(tcf_vendors, doc_texts["dse"])
        if vendor_findings:
            for r in results:
                if r.doc_type == "dse":
                    for vf in vendor_findings:
                        r.checks.append(CheckItem(**vf))
        vvt_entries = map_vendors_to_vvt(tcf_vendors)

    # Step 4: Extract profile hints from documents (92-95%)
    _update(check_id, "Profil wird aus Dokumenten extrahiert...", 93)
    from compliance.services.profile_extractor import (
        extract_profile_from_documents,
    )
    extracted_profile = extract_profile_from_documents(doc_texts, profile_dict)

    # Step 4b: Determine scenario per document
    for r in results:
        if r.error:
            r.scenario = "skip"
        elif r.completeness_pct < 30:
            r.scenario = "regenerate"
        elif r.completeness_pct < 95:
            r.scenario = "fix"
        else:
            r.scenario = "import"

    # Step 4c: Always render all 8 canonical doc types. Missing types
    # are differentiated:
    #   - Discovery was tried but found nothing -> 'Auf der Website
    #     nicht gefunden' (suggest user provides URL manually)
    #   - No submitted URLs at all -> 'Nicht eingereicht'
    attempted = {
        e["doc_type"] for e in doc_entries if e.get("discovery_attempted")
    }
    results = _pad_results_with_missing(results, discovery_attempted=attempted)

    state["banner_result"] = banner_result
    state["banner_url"] = banner_url
    state["tcf_vendors"] = tcf_vendors
    state["vvt_entries"] = vvt_entries
    state["extracted_profile"] = extracted_profile
    state["results"] = results
