"""
Control Relevance Filter — filters out controls that are not relevant
for the analyzed document based on keyword matching.

Prevents false positives like C_TRANSPARENCY being recommended when
no AI usage is evident.
"""

import logging
import re

logger = logging.getLogger(__name__)

# Top controls with their relevance conditions.
# A control is only relevant if ANY keyword from 'requires_any' matches the text.
# If 'requires_any' is empty, the control is always relevant.
CONTROL_RELEVANCE: dict[str, dict] = {
    "C_TRANSPARENCY": {
        "description": "KI-Transparenz-Hinweis (Art. 52 AI Act)",
        "requires_any": [
            "künstliche intelligenz", "kuenstliche intelligenz",
            "artificial intelligence", "machine learning", "maschinelles lernen",
            "ki-gestützt", "ki-gestuetzt", "ai-powered", "ai system",
            "chatbot", "neural", "deep learning", "algorithmus", "algorithmen",
            "automatisierte entscheidung", "automated decision",
        ],
        "reason": "Nur relevant wenn KI/ML tatsaechlich eingesetzt wird",
    },
    "C_DSFA_REQUIRED": {
        "description": "Datenschutz-Folgenabschaetzung durchfuehren",
        "requires_any": [
            "gesundheit", "biometrisch", "genetisch", "health", "biometric",
            "scoring", "profiling", "systematisch", "umfangreich",
            "videoüberwachung", "videoueberwachung", "kamera",
            "minderjährig", "minderjaehrig", "kinder",
        ],
        "reason": "Nur bei hohem Risiko (Art. 9 Daten, Profiling, Ueberwachung)",
    },
    "C_ART22_INFO": {
        "description": "Info ueber automatisierte Einzelentscheidung (Art. 22 DSGVO)",
        "requires_any": [
            "automatisierte entscheidung", "automated decision", "scoring",
            "bonitaet", "kredit", "rating", "algorithmische entscheidung",
            "profiling", "klarna", "ratenzahlung",
        ],
        "reason": "Nur bei automatisierten Einzelentscheidungen mit Rechtswirkung",
    },
    "C_DPO_REQUIRED": {
        "description": "Datenschutzbeauftragten bestellen",
        "requires_any": [],  # Always relevant — empty means no filter
        "reason": "Generell relevant fuer Unternehmen",
    },
    "C_EXPLICIT_CONSENT": {
        "description": "Explizite Einwilligung einholen",
        "requires_any": [
            "cookie", "tracking", "analytics", "pixel", "marketing",
            "werbung", "newsletter", "remarketing", "retargeting",
            "einwilligung", "consent", "opt-in",
        ],
        "reason": "Nur bei Tracking/Marketing das Einwilligung erfordert",
    },
    "C_CHILD_PROTECTION": {
        "description": "Besonderer Schutz fuer Minderdjaehrige",
        "requires_any": [
            "kinder", "minderjährig", "minderjaehrig", "jugend",
            "under 16", "unter 16", "schüler", "schueler", "child",
        ],
        "reason": "Nur wenn Daten von Minderjaehrigen verarbeitet werden",
    },
    "C_THIRD_COUNTRY_SAFEGUARDS": {
        "description": "Drittlandtransfer absichern (Art. 44-49 DSGVO)",
        "requires_any": [
            "usa", "united states", "drittland", "drittst", "third countr",
            "standardvertragsklausel", "sccs", "binding corporate",
            "angemessenheitsbeschluss", "adequacy",
            "google", "meta", "facebook", "amazon", "microsoft", "apple",
            "cloudflare", "stripe", "paypal",
        ],
        "reason": "Nur bei Datentransfer in Drittlaender",
    },
}


def filter_controls(
    controls: list[str],
    source_text: str,
    intake_flags: dict | None = None,
) -> list[str]:
    """Filter controls based on relevance to the analyzed text.

    Returns only controls that are relevant (keyword match or no filter defined).
    """
    if not controls:
        return controls

    text_lower = source_text.lower()
    filtered = []
    removed = []

    for control in controls:
        # Extract control ID from string like "[C_TRANSPARENCY] Nutzer informieren..."
        control_id = _extract_control_id(control)

        if control_id and control_id in CONTROL_RELEVANCE:
            rules = CONTROL_RELEVANCE[control_id]
            keywords = rules["requires_any"]

            if not keywords:
                # No filter = always relevant
                filtered.append(control)
                continue

            # Check if any keyword matches
            if any(kw in text_lower for kw in keywords):
                filtered.append(control)
            else:
                # Also check intake flags as fallback
                if intake_flags and _check_flags(control_id, intake_flags):
                    filtered.append(control)
                else:
                    removed.append((control_id, rules["reason"]))
        else:
            # Unknown control — keep it (don't filter what we don't understand)
            filtered.append(control)

    if removed:
        logger.info(
            "Relevance filter removed %d controls: %s",
            len(removed),
            ", ".join(f"{cid} ({reason})" for cid, reason in removed),
        )

    return filtered


def _extract_control_id(control: str) -> str | None:
    """Extract control ID from '[C_XXX] description' format."""
    match = re.match(r"\[([A-Z_0-9]+)\]", control)
    return match.group(1) if match else None


def _check_flags(control_id: str, flags: dict) -> bool:
    """Check if intake flags make a control relevant."""
    flag_map = {
        "C_TRANSPARENCY": flags.get("ai_usage", False),
        "C_DSFA_REQUIRED": flags.get("health_data", False) or flags.get("biometric_data", False),
        "C_ART22_INFO": flags.get("automated_decisions", False),
        "C_EXPLICIT_CONSENT": flags.get("tracking", False) or flags.get("marketing", False),
        "C_CHILD_PROTECTION": flags.get("minor_data", False),
        "C_THIRD_COUNTRY_SAFEGUARDS": flags.get("cross_border_transfer", False),
    }
    return flag_map.get(control_id, False)
