"""
Vendor Assessment Cross-Check — checks consistency BETWEEN documents.

Analogous to banner_cookie_cross_check.py but for vendor contracts:
- AVV references SCC → is SCC document present?
- AVV references TOM annex → is TOM document uploaded?
- AVV mentions sub-processors → does sub-processor list match?
- AVV mentions third-country transfer → is transfer mechanism documented?

Returns CheckItem-compatible dicts (same format as cross_check_vendors_vs_dsi).
"""

import logging
import re

logger = logging.getLogger(__name__)


def cross_check_documents(
    doc_texts: dict[str, str],
    vendor_name: str,
) -> list[dict]:
    """Cross-check consistency between uploaded vendor documents.

    Args:
        doc_texts: Mapping of doc_type → extracted text
        vendor_name: The vendor being assessed

    Returns:
        List of CheckItem-compatible finding dicts.
    """
    findings: list[dict] = []

    avv_text = _get_text(doc_texts, ["avv", "auftragsverarbeitung", "dpa"])
    scc_text = _get_text(doc_texts, ["scc", "standardvertragsklauseln"])
    tom_text = _get_text(doc_texts, ["tom_annex", "tom_anlage", "tom"])
    sub_text = _get_text(doc_texts, ["sub_processor_list", "sub_processor", "unterauftragnehmer"])

    if not avv_text:
        # No AVV → biggest gap
        findings.append(_finding(
            "cross-no-avv",
            f"Kein AVV fuer '{vendor_name}' vorhanden",
            "CRITICAL",
            f"Ohne Auftragsverarbeitungsvertrag (AVV) nach Art. 28 DSGVO ist "
            f"jede Verarbeitung personenbezogener Daten durch '{vendor_name}' "
            f"rechtswidrig. Dies ist der schwerwiegendste Mangel.",
        ))
        return findings

    avv_lower = avv_text.lower()

    # ── AVV references TOM but no TOM document ──────────────────────
    tom_referenced = bool(re.search(
        r"(?:tom|technische[\s\S]{0,10}organisatorische|art(?:ikel)?\s*\.?\s*32|"
        r"anlage[\s\S]{0,20}(?:tom|sicherheit|massnahmen))",
        avv_lower,
    ))
    if tom_referenced and not tom_text:
        findings.append(_finding(
            "cross-tom-missing",
            "AVV verweist auf TOM-Anlage — Dokument fehlt",
            "HIGH",
            "Der AVV verweist auf technische und organisatorische Massnahmen "
            "(Art. 32 DSGVO), aber es wurde keine TOM-Anlage hochgeladen. "
            "Ohne TOM-Nachweis kann die Angemessenheit der Sicherheitsmassnahmen "
            "nicht beurteilt werden.",
        ))

    # ── AVV mentions third-country but no SCC ───────────────────────
    third_country = bool(re.search(
        r"(?:drittland|third\s+country|usa|united\s+states|nicht[\s-]?(?:eu|ewr)|"
        r"ausserhalb\s+(?:des\s+)?(?:eu|ewr|europaeischen))",
        avv_lower,
    ))
    scc_referenced = bool(re.search(
        r"(?:standardvertragsklausel|scc|standard\s+contractual|2021/914)",
        avv_lower,
    ))
    if third_country and not scc_text and not scc_referenced:
        findings.append(_finding(
            "cross-scc-missing",
            "AVV erwaehnt Drittlandtransfer — keine SCC vorhanden",
            "CRITICAL",
            "Der AVV erwaehnt Datenverarbeitung in einem Drittland, "
            "aber es wurden keine Standardvertragsklauseln (SCC) hochgeladen "
            "und der AVV verweist auch nicht auf ein Data Privacy Framework. "
            "Ohne Transfermechanismus ist die Uebermittlung rechtswidrig "
            "(Art. 44-49 DSGVO, EuGH Schrems II C-311/18).",
        ))

    # ── AVV mentions sub-processors but no list ─────────────────────
    sub_mentioned = bool(re.search(
        r"(?:unterauftragnehmer|sub[\s-]?processor|unterauftragsverarbeiter|"
        r"weitere[rn]?\s+auftragsverarbeiter)",
        avv_lower,
    ))
    if sub_mentioned and not sub_text:
        findings.append(_finding(
            "cross-sub-list-missing",
            "AVV erwaehnt Unterauftragnehmer — Liste fehlt",
            "HIGH",
            "Der AVV regelt den Einsatz von Unterauftragsverarbeitern, "
            "aber es wurde keine Sub-Processor-Liste hochgeladen. "
            "Art. 28(2) DSGVO verlangt, dass der Verantwortliche "
            "ueber alle Unterauftragnehmer informiert ist.",
        ))

    # ── SCC present but no TIA referenced ───────────────────────────
    if scc_text:
        scc_lower = scc_text.lower()
        tia_present = bool(re.search(
            r"(?:transfer\s+impact|uebermittlungs[\s-]?risiko|"
            r"klausel\s+14|clause\s+14|risikobewertung[\s\S]{0,50}drittland)",
            scc_lower,
        ))
        if not tia_present:
            findings.append(_finding(
                "cross-scc-no-tia",
                "SCC vorhanden aber kein Transfer Impact Assessment (TIA)",
                "HIGH",
                "Standardvertragsklauseln wurden hochgeladen, aber ein "
                "Transfer Impact Assessment (TIA) fehlt oder wird nicht "
                "referenziert. Klausel 14 der SCC 2021 verlangt eine "
                "Bewertung der Rechtslage im Zielland (EuGH Schrems II).",
            ))

    # ── TOM present but incomplete ──────────────────────────────────
    if tom_text:
        tom_lower = tom_text.lower()
        encryption_mentioned = bool(re.search(
            r"(?:verschl(?:ue|ü)sselung|encryption|aes|tls|ssl)", tom_lower,
        ))
        if not encryption_mentioned:
            findings.append(_finding(
                "cross-tom-no-encryption",
                "TOM-Anlage erwaehnt keine Verschluesselung",
                "HIGH",
                "Die TOM-Anlage beschreibt keine Verschluesselungsmassnahmen. "
                "Art. 32(1)(a) DSGVO nennt Verschluesselung explizit als "
                "Sicherheitsmassnahme. Fehlende Verschluesselung ist einer "
                "der haeufigsten Beanstandungspunkte bei Audits.",
            ))

    logger.info("Cross-check: %d findings for vendor '%s'",
                len(findings), vendor_name)
    return findings


def _get_text(doc_texts: dict[str, str], keys: list[str]) -> str:
    """Get text for the first matching doc_type key."""
    for k in keys:
        if k in doc_texts:
            return doc_texts[k]
    return ""


def _finding(id: str, label: str, severity: str, hint: str) -> dict:
    """Create a CheckItem-compatible finding dict."""
    return {
        "id": id,
        "label": label,
        "passed": False,
        "severity": severity,
        "level": 1,
        "parent": None,
        "skipped": False,
        "matched_text": "",
        "hint": hint,
        "source": "contract_cross_check",
    }
