"""
Document Scope Resolver — determines which legal documents are required
based on company flags (website, ecommerce, SaaS, hardware, AI, etc.).

Deterministic, no LLM needed. Complements the Applicability Engine
(which handles Controls) with a document-level compliance layer.

Usage:
    result = resolve_required_documents(
        flags={"has_website": True, "has_ecommerce": True, "distance_selling": True},
        jurisdiction="DE",
    )
    # result["required_documents"] → list of required document types
    # result["assessment"] → confidence, escalation, reasoning
"""

from __future__ import annotations

import logging
from dataclasses import dataclass, field, asdict
from typing import Any, Optional

logger = logging.getLogger(__name__)


# ---------------------------------------------------------------------------
# Document Requirement Rules
# ---------------------------------------------------------------------------

DOCUMENT_RULES: dict[str, dict[str, Any]] = {
    # === IMMER bei Website ===
    "impressum": {
        "label": "Impressum / Anbieterkennzeichnung",
        "required_if_any": ["has_website"],
        "jurisdiction": ["DE", "AT"],
        "legal_basis": "TMG § 5 / MedienG § 24",
        "mandatory": True,
        "category": "base",
    },
    "privacy_policy": {
        "label": "Datenschutzerklaerung",
        "required_if_any": ["has_website", "has_user_accounts"],
        "jurisdiction": ["DE", "AT", "EU"],
        "legal_basis": "DSGVO Art. 13/14",
        "mandatory": True,
        "category": "base",
    },

    # === Bei Tracking/Cookies ===
    "cookie_banner": {
        "label": "Cookie-Banner mit Einwilligungsmanagement",
        "required_if_any": ["uses_tracking", "uses_cookies_marketing"],
        "not_required_if": ["strictly_necessary_cookies_only"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "TTDSG § 25, ePrivacy-RL 2002/58/EG",
        "mandatory": True,
        "category": "tracking",
    },
    "cookie_policy": {
        "label": "Cookie-Richtlinie / Cookie-Details",
        "required_if_any": ["uses_tracking", "uses_cookies_marketing"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "TTDSG § 25",
        "mandatory": True,
        "category": "tracking",
        "note": "Kann Teil der Datenschutzerklaerung sein",
    },

    # === Bei E-Commerce ===
    "terms_and_conditions": {
        "label": "Allgemeine Geschaeftsbedingungen (AGB)",
        "required_if_any": ["has_ecommerce", "has_saas"],
        "jurisdiction": ["DE", "AT"],
        "legal_basis": "BGB §§ 305ff",
        "mandatory": True,
        "category": "ecommerce",
    },
    "agb_checkout_summary": {
        "label": "Vertragswesentliche Informationen im Checkout",
        "required_if_any": ["has_checkout"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 8(2), BGB § 312j",
        "mandatory": True,
        "category": "ecommerce",
        "note": "Preis, Laufzeit, Kuendigungsbedingungen VOR Bestellung sichtbar",
    },
    "withdrawal_policy": {
        "label": "Widerrufsbelehrung",
        "required_if_any": ["distance_selling"],
        "not_required_if": ["b2b_only"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 9-16, BGB § 355ff",
        "mandatory": True,
        "category": "ecommerce",
    },
    "pricing_transparency": {
        "label": "Preisangaben / Preistransparenz",
        "required_if_any": ["has_ecommerce"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "PAngV, Consumer Rights Directive Art. 6(1)(e)",
        "mandatory": True,
        "category": "ecommerce",
    },
    "shipping_information": {
        "label": "Versand- und Lieferinformationen",
        "required_if_any": ["sells_physical_products"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 6(1)(g)",
        "mandatory": True,
        "category": "ecommerce",
    },
    "payment_terms": {
        "label": "Zahlungsbedingungen und akzeptierte Zahlungsmittel",
        "required_if_any": ["has_ecommerce"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 6(1)(g), BGB § 312d",
        "mandatory": True,
        "category": "ecommerce",
    },

    # === Digitaler Verkauf ===
    "digital_content_terms": {
        "label": "Vertragsbedingungen fuer digitale Inhalte",
        "required_if_any": ["sells_digital_products"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 5(2), BGB § 327ff",
        "mandatory": True,
        "category": "digital",
    },
    "no_withdrawal_notice": {
        "label": "Hinweis auf Widerrufsverzicht bei sofortiger Ausfuehrung",
        "required_if_any": ["sells_digital_products"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 16(m), BGB § 356(5)",
        "mandatory": True,
        "category": "digital",
        "note": "Checkbox: Zustimmung zur sofortigen Ausfuehrung + Kenntnis Widerrufsverlust",
    },

    # === SaaS ===
    "terms_of_service": {
        "label": "Nutzungsbedingungen / Terms of Service",
        "required_if_any": ["has_saas"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "BGB, DSGVO",
        "mandatory": True,
        "category": "saas",
    },
    "service_description": {
        "label": "Leistungsbeschreibung",
        "required_if_any": ["has_saas"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 6(1)(a), BGB § 312d",
        "mandatory": True,
        "category": "saas",
    },
    "data_processing_agreement": {
        "label": "Auftragsverarbeitungsvertrag (AVV/DPA)",
        "required_if_any": ["has_saas"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "DSGVO Art. 28",
        "mandatory": True,
        "category": "saas",
        "note": "Pflicht wenn personenbezogene Daten im Auftrag verarbeitet werden",
    },
    "sla": {
        "label": "Service Level Agreement (SLA)",
        "required_if_any": ["has_saas"],
        "not_required_if": ["b2c_only"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Vertragsrecht",
        "mandatory": False,
        "category": "saas",
        "note": "Empfohlen fuer B2B SaaS",
    },
    "acceptable_use_policy": {
        "label": "Acceptable Use Policy / Nutzungsrichtlinie",
        "required_if_any": ["has_saas", "operates_marketplace"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Vertragsrecht, DSA (EU) 2022/2065",
        "mandatory": False,
        "category": "saas",
    },

    # === KI ===
    "ai_transparency_notice": {
        "label": "KI-Transparenzhinweis",
        "required_if_any": ["uses_ai"],
        "jurisdiction": ["EU"],
        "legal_basis": "AI Act Art. 52",
        "mandatory": True,
        "category": "ai",
    },
    "automated_decision_explanation": {
        "label": "Erklaerung automatisierter Entscheidungen",
        "required_if_any": ["automated_decisions"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "DSGVO Art. 22",
        "mandatory": True,
        "category": "ai",
    },

    # === Hardware ===
    "warranty_information": {
        "label": "Gewaehrleistungs- und Garantieinformationen",
        "required_if_any": ["sells_physical_products"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "BGB § 437ff, Warenkauf-RL (EU) 2019/771",
        "mandatory": True,
        "category": "hardware",
    },
    "return_policy": {
        "label": "Rueckgabe- und Ruecksendebedingungen",
        "required_if_any": ["distance_selling"],
        "not_required_if": ["b2b_only"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Consumer Rights Directive Art. 9-16",
        "mandatory": True,
        "category": "hardware",
    },
    "ce_conformity_declaration": {
        "label": "EU-Konformitaetserklaerung (CE)",
        "required_if_any": ["sells_regulated_products"],
        "jurisdiction": ["EU"],
        "legal_basis": "Maschinenverordnung (EU) 2023/1230, Blue Guide",
        "mandatory": True,
        "category": "hardware",
    },
    "product_safety_instructions": {
        "label": "Sicherheitshinweise und Bedienungsanleitung",
        "required_if_any": ["sells_regulated_products"],
        "jurisdiction": ["EU"],
        "legal_basis": "Produktsicherheitsverordnung (EU) 2023/988",
        "mandatory": True,
        "category": "hardware",
    },

    # === Umwelt / Batterie ===
    "weee_information": {
        "label": "WEEE-Registrierung und Entsorgungshinweise",
        "required_if_any": ["sells_electronics"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "WEEE-RL 2012/19/EU, ElektroG",
        "mandatory": True,
        "category": "environmental",
    },
    "battery_disposal_information": {
        "label": "Batterie-Entsorgungshinweise",
        "required_if_any": ["contains_battery"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "Batterieverordnung (EU) 2023/1542",
        "mandatory": True,
        "category": "environmental",
    },

    # === Marketplace ===
    "marketplace_seller_terms": {
        "label": "Haendler-AGB / Plattform-Teilnahmebedingungen",
        "required_if_any": ["operates_marketplace"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "P2B-VO (EU) 2019/1150",
        "mandatory": True,
        "category": "marketplace",
    },
    "marketplace_ranking_transparency": {
        "label": "Transparenz zu Ranking- und Listungskriterien",
        "required_if_any": ["operates_marketplace"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "P2B-VO (EU) 2019/1150 Art. 5",
        "mandatory": True,
        "category": "marketplace",
    },

    # === Subscription ===
    "subscription_cancellation_terms": {
        "label": "Kuendigungsbedingungen bei Abonnements",
        "required_if_any": ["subscription_model"],
        "jurisdiction": ["DE", "EU"],
        "legal_basis": "BGB § 309 Nr. 9, Faire-Verbrauchervertraege-RL",
        "mandatory": True,
        "category": "subscription",
    },
}

# Signals that indicate the company is B2C (not B2B-only)
_B2C_INDICATORS = {"distance_selling", "has_checkout", "sells_digital_products"}


# ---------------------------------------------------------------------------
# Resolver
# ---------------------------------------------------------------------------


@dataclass
class DocumentRequirement:
    """A single required document."""
    document_type: str
    label: str
    mandatory: bool
    legal_basis: str
    category: str
    reason: str
    note: Optional[str] = None


@dataclass
class DocumentAssessment:
    """Assessment of document requirements completeness."""
    confidence: float = 1.0
    escalation_flag: bool = False
    escalation_reason: Optional[str] = None
    reasoning: str = ""
    warnings: list = field(default_factory=list)


def resolve_required_documents(
    flags: dict[str, bool],
    jurisdiction: str = "DE",
) -> dict[str, Any]:
    """Determine which legal documents are required based on company flags.

    Args:
        flags: dict of scope signals (e.g., has_website, has_ecommerce, uses_ai)
        jurisdiction: country code (DE, AT, EU)

    Returns:
        dict with required_documents, total_required, total_recommended, assessment
    """
    active_signals = {k for k, v in flags.items() if v is True}
    required = []
    recommended = []

    for doc_type, rule in DOCUMENT_RULES.items():
        # Check jurisdiction — DE and AT are part of EU
        rule_jurisdictions = rule.get("jurisdiction", ["DE", "EU"])
        jurisdiction_match = (
            jurisdiction in rule_jurisdictions
            or (jurisdiction in ("DE", "AT") and "EU" in rule_jurisdictions)
        )
        if not jurisdiction_match:
            continue

        # Check if any required signal is active
        triggers = rule.get("required_if_any", [])
        if not any(sig in active_signals for sig in triggers):
            continue

        # Check exclusions
        exclusions = rule.get("not_required_if", [])
        if any(sig in active_signals for sig in exclusions):
            continue

        # Determine triggered signals for reasoning
        matched_signals = [sig for sig in triggers if sig in active_signals]
        reason = f"Aktiv wegen: {', '.join(matched_signals)}"

        doc = DocumentRequirement(
            document_type=doc_type,
            label=rule.get("label", doc_type),
            mandatory=rule.get("mandatory", True),
            legal_basis=rule.get("legal_basis", ""),
            category=rule.get("category", "other"),
            reason=reason,
            note=rule.get("note"),
        )

        if doc.mandatory:
            required.append(doc)
        else:
            recommended.append(doc)

    # Assessment
    assessment = _assess_documents(flags, active_signals, required, recommended)

    return {
        "required_documents": [asdict(d) for d in required],
        "recommended_documents": [asdict(d) for d in recommended],
        "total_required": len(required),
        "total_recommended": len(recommended),
        "jurisdiction": jurisdiction,
        "active_flags": sorted(active_signals),
        "assessment": asdict(assessment),
    }


def _assess_documents(
    flags: dict[str, bool],
    active_signals: set[str],
    required: list[DocumentRequirement],
    recommended: list[DocumentRequirement],
) -> DocumentAssessment:
    """Compute assessment for document requirements."""
    assessment = DocumentAssessment()
    warnings = []

    # Confidence scoring
    score = 0.0

    # Has website flag? (+0.20)
    if "has_website" in active_signals:
        score += 0.20
    else:
        warnings.append("has_website nicht gesetzt — Basis-Dokumente koennten fehlen")

    # E-commerce flags specified? (+0.20)
    ecom_flags = {"has_ecommerce", "has_checkout", "distance_selling", "b2b_only"}
    if active_signals & ecom_flags:
        score += 0.20
    elif "has_website" in active_signals:
        warnings.append("Keine E-Commerce-Flags — unklar ob Webshop vorhanden")

    # Tracking specified? (+0.15)
    tracking_flags = {"uses_tracking", "uses_cookies_marketing", "strictly_necessary_cookies_only"}
    if active_signals & tracking_flags:
        score += 0.15
    else:
        warnings.append("Keine Cookie/Tracking-Flags — Cookie-Banner-Pflicht unklar")

    # Products specified? (+0.15)
    product_flags = {"sells_physical_products", "sells_digital_products", "sells_regulated_products"}
    if active_signals & product_flags:
        score += 0.15

    # Enough signals overall? (+0.15)
    if len(active_signals) >= 4:
        score += 0.15
    elif len(active_signals) >= 2:
        score += 0.10

    # Documents found? (+0.15)
    if len(required) >= 3:
        score += 0.15
    elif len(required) >= 1:
        score += 0.05

    assessment.confidence = round(min(score, 1.0), 2)

    # Escalation detection
    escalation_reasons = []

    # E-commerce without distance_selling flag
    if "has_ecommerce" in active_signals and "distance_selling" not in active_signals and "b2b_only" not in active_signals:
        escalation_reasons.append(
            "E-Commerce aktiv aber distance_selling/b2b_only nicht spezifiziert — "
            "Widerrufsrecht-Pflicht unklar"
        )

    # Marketplace without payment clarification
    if "operates_marketplace" in active_signals and "operates_payment_service" not in active_signals:
        escalation_reasons.append(
            "Marketplace aktiv — Pruefung ob eigene Zahlungsabwicklung oder externer PSP"
        )

    # Very few flags
    if len(active_signals) < 2:
        escalation_reasons.append(
            "Zu wenige Flags fuer belastbare Dokumenten-Ableitung"
        )

    if escalation_reasons:
        assessment.escalation_flag = True
        assessment.escalation_reason = " | ".join(escalation_reasons)
        assessment.confidence = min(assessment.confidence, 0.75)

    # Reasoning
    parts = []
    parts.append(f"{len(active_signals)} Flags aktiv: {', '.join(sorted(active_signals))}")
    parts.append(f"{len(required)} Pflichtdokumente, {len(recommended)} empfohlen")

    categories = set(d.category for d in required)
    if categories:
        parts.append(f"Kategorien: {', '.join(sorted(categories))}")

    if warnings:
        parts.append(f"Hinweise: {'; '.join(warnings)}")

    if assessment.escalation_flag:
        parts.append(f"ESKALATION: {assessment.escalation_reason}")

    assessment.reasoning = ". ".join(parts) + "."
    assessment.warnings = warnings

    return assessment
