"""Phase D-2 — Vendor finalize: enrich + normalize + library fallback.

Covers (in the original Step 5 of `_run_compliance_check`):
  - Cookie-Library-Fallback (P52 Lite) — when < 20 vendors but many
    after-accept cookies, resolve via library
  - Vendor-Normalizer (Google-Familie dedup, garbage filter)
  - Detail-modal enrichment from Phase G (P50) + TDM-opt-out sentinel
  - Cookie-Behavior-Validator (P59b) — 3-Tier severity findings
  - Implicit cookies detection (P61) — GTM brings GA/GCL/DoubleClick
  - validate_vendor_urls + score_vendors + cookie-function classify
  - Vendor-Redundanz (O4) + EU-Alternativen + Cost/Savings
"""

from __future__ import annotations

import logging
import re

logger = logging.getLogger(__name__)


async def run_phase_d2(state: dict) -> None:
    """Vendor finalize stages + redundancy. Mutates state in place."""
    cmp_vendors = state["cmp_vendors"]
    cookie_text = state.get("cookie_text", "")
    banner_result = state["banner_result"]
    banner_url = state["banner_url"]
    profile = state["profile"]
    business_scope = state["business_scope"]

    tdm_opt_out_notice = ""
    cookie_behavior_findings: list[dict] = []
    redundancy_report = None

    try:
        from compliance.services.cookie_link_validator import (
            score_vendors, validate_vendor_urls,
        )

        # Cookie-Library-Fallback (P52 Lite): wenn weiterhin wenige
        # Vendors aber viele after_accept-Cookies, aus Library auflösen.
        # VW-Lehre: 6 LLM-Grob-Vendors reichen NICHT — die Library
        # holt 30+ weitere aus den Cookie-Namen + Cookie-Doc-Pattern.
        # Schwelle: immer probieren wenn < 20 Vendors.
        if banner_result and len(cmp_vendors) < 20:
            try:
                from compliance.services.cookie_to_vendor_fallback import (
                    fallback_vendors_for_run,
                )
                from database import SessionLocal as _SLfb
                _fb_db = _SLfb()
                try:
                    extra = fallback_vendors_for_run(
                        _fb_db, banner_result, len(cmp_vendors),
                        cookie_doc_text=cookie_text,
                    )
                    if extra:
                        existing_names = {(v.get("name") or "").strip().lower()
                                          for v in cmp_vendors}
                        for v in extra:
                            if v["name"].lower() in existing_names:
                                continue
                            cmp_vendors.append(v)
                        logger.info(
                            "Cookie-Library-Fallback: cmp_vendors %d -> %d",
                            len(cmp_vendors) - len(extra), len(cmp_vendors),
                        )
                finally:
                    _fb_db.close()
            except Exception as e:
                logger.warning("Cookie-Library-Fallback skipped: %s", e)

        # Vendor-Normalizer: Dedup (Google-Familie etc) + Garbage-Filter
        try:
            from compliance.services.vendor_normalizer import (
                normalize_vendors as _norm_v,
            )
            cmp_vendors = _norm_v(cmp_vendors)
        except Exception as e:
            logger.warning("vendor_normalizer skipped: %s", e)

        # P50: enrich vendors with per-vendor detail-modal-extracts
        if cmp_vendors and banner_result:
            vendor_details = banner_result.get("vendor_details") or []
            # P50f: filter out TDM-opt-out sentinel
            tdm_sentinel = next((v for v in vendor_details
                                 if v.get("name") == "__TDM_OPTOUT__"), None)
            if tdm_sentinel:
                tdm_opt_out_notice = tdm_sentinel.get("description", "")
                logger.info("P50f: TDM opt-out — skipped detail-enrichment for vendors")
                vendor_details = [v for v in vendor_details
                                  if v.get("name") != "__TDM_OPTOUT__"]
            if vendor_details:
                details_by_name = {}
                for d in vendor_details:
                    n = (d.get("name") or "").strip().lower()
                    if n:
                        details_by_name[n] = d
                enriched = 0
                for v in cmp_vendors:
                    key = (v.get("name") or "").strip().lower()
                    d = details_by_name.get(key)
                    if not d:
                        for dn, dv in details_by_name.items():
                            if key in dn or dn in key:
                                d = dv
                                break
                    if not d:
                        continue
                    if not v.get("country") and (d.get("processing_company") or d.get("address")):
                        addr = d.get("address", "")
                        if re.search(r"\b(deutschland|germany|berlin|m(?:ue|ü)nchen|hamburg|stuttgart)\b", addr, re.I):
                            v["country"] = "DE"
                        elif re.search(r"\bireland|irland|dublin\b", addr, re.I):
                            v["country"] = "IE"
                        elif re.search(r"\busa|united states|california|new york|delaware\b", addr, re.I):
                            v["country"] = "US"
                    if not v.get("purpose"):
                        v["purpose"] = d.get("description", "")[:500]
                    if not v.get("opt_out_url"):
                        v["opt_out_url"] = d.get("opt_out_url", "")
                    if not v.get("privacy_policy_url"):
                        v["privacy_policy_url"] = d.get("privacy_url", "")
                    if not v.get("cookies"):
                        v["cookies"] = d.get("cookies", [])
                    v["purposes"] = d.get("purposes", [])
                    v["technologies"] = d.get("technologies", [])
                    if not v.get("persistence"):
                        v["persistence"] = d.get("retention", "")
                    v["processing_company"] = d.get("processing_company", "")
                    v["address"] = d.get("address", "")
                    enriched += 1
                logger.info("P50: enriched %d/%d vendors with detail-modal data",
                            enriched, len(cmp_vendors))

        # P59b: Cookie-Behavior-Validator
        if banner_result:
            cookies_detailed = banner_result.get("cookies_detailed") or []
            if cookies_detailed:
                cb_session = None
                try:
                    from database import SessionLocal
                    from compliance.services.cookie_behavior_validator import (
                        validate_cookie_behavior,
                    )
                    from urllib.parse import urlparse
                    fp_domain = ""
                    if banner_url:
                        fp_domain = urlparse(banner_url).netloc.replace("www.", "")
                    cb_session = SessionLocal()
                    cookie_behavior_findings = validate_cookie_behavior(
                        cb_session, cookies_detailed,
                        network_requests=[],  # TODO Layer B in P59d
                        first_party_domain=fp_domain,
                    )
                    if cookie_behavior_findings:
                        sevs = {f["severity"] for f in cookie_behavior_findings}
                        logger.info(
                            "P59b: Cookie-Behavior-Check %d findings (severities: %s) "
                            "ueber %d Cookies",
                            len(cookie_behavior_findings),
                            sorted(sevs), len(cookies_detailed),
                        )
                        banner_result["cookie_behavior_findings"] = (
                            cookie_behavior_findings
                        )
                    else:
                        logger.info(
                            "P59b: Cookie-Behavior-Check 0 findings ueber %d Cookies "
                            "(library miss / clean)", len(cookies_detailed),
                        )
                except Exception as cb_err:
                    logger.warning("P59b Cookie-Behavior-Check failed: %s", cb_err)
                finally:
                    if cb_session is not None:
                        try:
                            cb_session.close()
                        except Exception:
                            pass

        # P61: "Untergeschobene Cookies"
        if banner_result and cmp_vendors:
            try:
                from compliance.services.vendor_package_cookies import (
                    detect_implicit_cookies,
                )
                declared = [v.get("name", "") for v in cmp_vendors if v.get("name")]
                actual_cookies: list[str] = []
                for phase_data in (banner_result.get("phases") or {}).values():
                    if isinstance(phase_data, dict):
                        for ck in (phase_data.get("cookies") or []):
                            if isinstance(ck, dict) and ck.get("name"):
                                actual_cookies.append(ck["name"])
                implicit_findings = detect_implicit_cookies(
                    declared, actual_cookies_set=actual_cookies or None,
                )
                if implicit_findings:
                    banner_result["implicit_vendor_findings"] = implicit_findings
                    logger.info(
                        "P61: %d implicit vendor-package items detected "
                        "(%d cookies + %d vendors)",
                        len(implicit_findings),
                        sum(1 for f in implicit_findings if f["implicit"]["type"] == "cookie"),
                        sum(1 for f in implicit_findings if f["implicit"]["type"] == "vendor"),
                    )
            except Exception as p61_err:
                logger.warning("P61 implicit-vendor detection failed: %s", p61_err)

        if cmp_vendors:
            logger.info("VVT: %d vendors extracted, validating links",
                        len(cmp_vendors))
            cmp_vendors = await validate_vendor_urls(cmp_vendors)
            cmp_vendors = score_vendors(cmp_vendors)
            try:
                from compliance.services.cookie_function_classifier import (
                    annotate_vendor_cookies,
                )
                cmp_vendors = [annotate_vendor_cookies(v) for v in cmp_vendors]
            except Exception as e:
                logger.warning("Cookie function classification skipped: %s", e)
    except Exception as e:
        logger.warning("VVT vendor finalize skipped: %s", e)

    # Vendor-Redundanz + EU-Alternativen + Cost/Savings (O4)
    try:
        from compliance.services.vendor_cost_estimator import infer_company_tier
        from compliance.services.vendor_redundancy import (
            analyze as analyze_redundancy,
        )
        if cmp_vendors:
            bp_dict = {
                "type": getattr(profile, "business_type", ""),
                "features": list(business_scope),
            }
            ctier = infer_company_tier(bp_dict)
            redundancy_report = analyze_redundancy(cmp_vendors, company_tier=ctier)
            logger.info(
                "Redundanz: %d Kategorien mit Mehrfach-Anbietern, "
                "Spar-Schaetzung %s pro Jahr (company_tier=%s)",
                redundancy_report["summary"]["redundancy_count"],
                redundancy_report["summary"]["estimated_saving_pct"],
                ctier,
            )
    except Exception as e:
        logger.warning("Vendor redundancy analysis skipped: %s", e)

    state["cmp_vendors"] = cmp_vendors
    state["tdm_opt_out_notice"] = tdm_opt_out_notice
    state["cookie_behavior_findings"] = cookie_behavior_findings
    state["redundancy_report"] = redundancy_report
