"""Phase D-3-Bot — Bottom HTML blocks + final composition.

Covers (in the original Step 5):
  - P71 JC-vs-AVV Entscheidungsbaum (only when DSE ambig)
  - P6/P53/P55 Branchen-Kontext + Site-History
  - P106 Internal-Checks-Block
  - P85 Banner-Screenshot
  - A Audit-Quality-Checks (Banner-Detect-Failure, vendor-extract dünn)
  - P82 GF-1-Pager
  - Doc-Input-Warnings (User text in falsches Feld gepastet)
  - P86 Branchen-Benchmark
  - P84 Diff-Mode (since-last-run delta)
  - Final HTML composition

NOTE: in the original code `audit_quality_findings` was used by
build_gf_one_pager_html BEFORE it was initialised — a silent
UnboundLocalError caught by the surrounding try/except, so the
gf_one_pager block effectively never rendered. Here we run
audit-quality FIRST so the data is actually available.
"""

from __future__ import annotations

import logging

logger = logging.getLogger(__name__)


async def run_phase_d3_bot(state: dict) -> None:
    """Bottom blocks + assemble full_html. Mutates state in place."""
    check_id = state["check_id"]
    req = state["req"]
    doc_entries = state["doc_entries"]
    doc_texts = state["doc_texts"]
    banner_result = state["banner_result"]
    cmp_vendors = state["cmp_vendors"]
    mc_split = state["mc_split"]
    scorecard = state["scorecard"]
    prev_scorecard = state.get("prev_scorecard")
    mismatches = state.get("mismatches") or []
    site_name_for_exec = state.get("site_name_for_exec", "")
    domain_for_exec = state.get("domain_for_exec")
    html_blocks = state["html_blocks"]

    # P71: JC-vs-AVV Entscheidungsbaum
    jc_decision_html = ""
    try:
        from compliance.services.jc_avv_decision import (
            build_jc_avv_decision_html,
        )
        jc_decision_html = build_jc_avv_decision_html(doc_texts.get("dse"))
    except Exception as e:
        logger.warning("P71 jc_avv_decision skipped: %s", e)

    # P6/P53/P55 — Branchen-Kontext + Site-History
    industry_ctx_html = ""
    try:
        from compliance.services.industry_library import (
            build_industry_context_block_html, load_site_profile,
        )
        from database import SessionLocal as _SLib
        _ind_db = _SLib()
        try:
            ind = (req.scan_context or {}).get("industry") if req.scan_context else None
            site_prof = load_site_profile(_ind_db, domain_for_exec or "")
            industry_ctx_html = build_industry_context_block_html(ind, site_prof)
        finally:
            _ind_db.close()
    except Exception as e:
        logger.warning("industry context skipped: %s", e)

    # P106 — Internal-Checks-Block
    internal_checks_html = ""
    try:
        from compliance.services.mc_audit_type import (
            build_internal_checks_block_html,
        )
        ic = (mc_split or {}).get("internal_checks") or []
        if ic:
            internal_checks_html = build_internal_checks_block_html(ic)
            logger.info("P106: %d interne Checks (statt FAIL) im Block",
                        len(ic))
    except Exception as e:
        logger.warning("P106 internal_checks_html skipped: %s", e)

    # P85 — Banner-Screenshot
    banner_shot_html = ""
    try:
        from compliance.services.banner_screenshot_block import (
            build_banner_screenshot_html,
        )
        banner_shot_html = build_banner_screenshot_html(banner_result)
    except Exception as e:
        logger.warning("P85 banner-screenshot skipped: %s", e)

    # A — Audit-Quality-Checks (run BEFORE gf_one_pager so the data is
    # available — original code had this inverted, causing
    # UnboundLocalError silently caught).
    audit_quality_html = ""
    audit_quality_findings: list[dict] = []
    try:
        from compliance.services.audit_quality_checks import (
            build_audit_quality_block_html, run_all as run_audit_quality,
        )
        cookie_text_for_aq = doc_texts.get("cookie") or ""
        audit_quality_findings = run_audit_quality(
            banner_result, cookie_text_for_aq, cmp_vendors, doc_entries,
        )
        if audit_quality_findings:
            audit_quality_html = build_audit_quality_block_html(audit_quality_findings)
            logger.info("audit-quality: %d Vorbehalte erkannt",
                        len(audit_quality_findings))
    except Exception as e:
        logger.warning("audit-quality-checks failed: %s", e)

    # P82: GF-1-Pager (now has the audit_quality_findings filled)
    gf_one_pager_html = ""
    try:
        from compliance.services.gf_one_pager import build_gf_one_pager_html
        gf_one_pager_html = build_gf_one_pager_html(
            site_name=site_name_for_exec,
            scorecard=scorecard,
            previous_scorecard=prev_scorecard,
            banner_result=banner_result,
            library_mismatch_findings=mismatches,
            scan_context=req.scan_context,
            audit_quality_findings=audit_quality_findings,
        )
    except Exception as e:
        logger.warning("P82 GF-1-pager skipped: %s", e)

    # Doc-Input-Warnings — wenn User Text ins falsche Feld gepastet hat
    input_warn_html = ""
    try:
        from compliance.services.doc_input_warnings import (
            build_warnings_block_html, collect_warnings,
        )
        warns = collect_warnings(doc_entries)
        if warns:
            input_warn_html = build_warnings_block_html(warns)
            logger.info("doc-input-warnings: %d Mismatches gefunden", len(warns))
    except Exception as e:
        logger.warning("doc-input-warnings skipped: %s", e)

    # P86: Branchen-Benchmark
    bench_html = ""
    try:
        from compliance.services.industry_benchmark import (
            _extract_score, build_benchmark_html, compute_benchmark,
        )
        from database import SessionLocal as _SLb
        industry = (req.scan_context or {}).get("industry") if req.scan_context else None
        curr_score = _extract_score(banner_result)
        if industry and curr_score is not None:
            _b_db = _SLb()
            try:
                bench = compute_benchmark(
                    _b_db, industry, curr_score, check_id,
                )
                if bench:
                    bench_html = build_benchmark_html(bench)
            finally:
                _b_db.close()
    except Exception as e:
        logger.warning("P86 industry-benchmark skipped: %s", e)

    # P84: Diff-Mode
    diff_html = ""
    try:
        from compliance.services.run_diff import (
            build_diff_block_html, compute_diff,
        )
        from database import SessionLocal as _SL
        _diff_db = _SL()
        try:
            diff = compute_diff(
                _diff_db, check_id, domain_for_exec or "",
                banner_result, scorecard,
            )
            if diff:
                diff_html = build_diff_block_html(diff)
        finally:
            _diff_db.close()
    except Exception as e:
        logger.warning("P84 diff-mode skipped: %s", e)

    # B1 / B3 cross-cutting findings (own renderers, may be empty).
    reachability_html = state.get("reachability_html", "")
    retention_html = state.get("retention_html", "")

    # Reihenfolge — Sales-optimiert.
    # B1 (Reachability) sits next to critical because it's an Art.7-Abs.3
    # finding. B3 (Retention) sits next to cookie_audit because both
    # are 3-source comparisons of cookie metadata.
    full_html = (
        gf_one_pager_html + audit_quality_html + input_warn_html
        + bench_html + diff_html
        + html_blocks["critical_html"] + reachability_html
        + html_blocks["scope_disclaimer_html"]
        + html_blocks["exec_summary_html"]
        + html_blocks["cookie_arch_html"] + html_blocks["summary_html"]
        + html_blocks["scanned_html"] + html_blocks["profile_html"]
        + html_blocks["scorecard_html"] + internal_checks_html
        + html_blocks["redundancy_html"]
        + industry_ctx_html
        + banner_shot_html
        + html_blocks["providers_html"] + html_blocks["banner_deep_html"]
        + html_blocks["cookie_audit_html"] + retention_html
        + html_blocks["tcf_authority_html"]
        + html_blocks["entropy_html"]
        + html_blocks["network_trace_html"]
        + html_blocks["library_mismatch_html"]
        + html_blocks["consistency_html"] + html_blocks["signals_html"]
        + html_blocks["solutions_html"]
        + jc_decision_html
        + html_blocks["vvt_html"] + html_blocks["report_html"]
    )

    state["audit_quality_findings"] = audit_quality_findings

    # MAIL_RENDER_V2 — opt-in unified layout. Default keeps the legacy
    # composition so we can A/B compare in Mailpit.
    try:
        from compliance.services.mail_render_v2._compose import (
            compose_v2, is_v2_enabled,
        )
        if is_v2_enabled():
            full_html = compose_v2(state)
            logger.info("MAIL_RENDER_V2 active: %d bytes", len(full_html))
    except Exception as e:
        logger.warning("MAIL_RENDER_V2 fallback to legacy: %s", e)

    state["full_html"] = full_html
