"""Klassifikation von Impressum-Sektionen — was gehört rein, was nicht.

Pflicht-Sektionen (gehören ins Impressum):
  - Anbieter (Name, Anschrift)
  - Kontakt (Tel/E-Mail)
  - Vertretungsberechtigte
  - Handelsregister + USt-IdNr.
  - § 18 MStV (Verantwortlicher)
  - § 36 VSBG + Art. 14 EU-VO 524/2013
  - Aufsichtsbehoerde + Berufsangaben (regulated)

Empfohlen-anders-platziert (Best-Practice in eigenem Footer-Bereich):
  - Copyright / Urheberrecht / Marken
  - Bilder / Lizenzen / Quellen
  - Haftungsausschluss / Disclaimer / Disclaimer-Links
  - Nutzungsbedingungen / AGB
  - ElektroG / WEEE / VerpackG / BattG (Produkt-Compliance)
  - Datenschutz-Erklaerung (eigene Seite)
"""

from __future__ import annotations

import re
from dataclasses import dataclass, field
from typing import Pattern


@dataclass(frozen=True)
class SectionPattern:
    """Eine Sektion die wir im Impressum erkennen können."""
    section_id: str
    label: str
    # Heading-Pattern: matched typischerweise H2/H3-artige Sektions-
    # Überschriften innerhalb des Impressum-Texts.
    heading_patterns: tuple[Pattern[str], ...] = field(default_factory=tuple)
    # In welche Kategorie gehoert die Sektion?
    # 'mandatory'    = klassisches Impressum
    # 'recommended_separate' = gehoert besser in 'Legal'-Footer
    # 'product_compliance'   = ElektroG/WEEE etc, kontextabhaengig
    category: str = "recommended_separate"
    # Best-Practice-Vorschlag wohin der Inhalt umziehen sollte
    recommended_location: str = ""
    norm: str = ""


SECTIONS: tuple[SectionPattern, ...] = (
    SectionPattern(
        section_id="urheberrecht",
        label="Urheberrecht",
        heading_patterns=(
            re.compile(r"\bUrheberrecht(?:e|sschutz|svermerk)?\b",
                         re.IGNORECASE),
            re.compile(r"\bCopyright\b", re.IGNORECASE),
        ),
        category="recommended_separate",
        recommended_location="Footer-Reiter 'Legal' / Seite 'Copyright'",
        norm="UrhG — gehört nicht zwingend ins Impressum nach § 5 TMG",
    ),
    SectionPattern(
        section_id="bilder_lizenzen",
        label="Bilder & Lizenzen",
        heading_patterns=(
            re.compile(r"\bBild(?:er|nachweis|quellen)\s*[&und]+\s*Lizenz",
                         re.IGNORECASE),
            re.compile(r"\bLizenz(?:en|hinweis|nachweis)e?\b",
                         re.IGNORECASE),
            re.compile(r"\b(?:Bild|Foto|Image)\s*[:\-]\s*\w+",
                         re.IGNORECASE),
        ),
        category="recommended_separate",
        recommended_location="Footer-Reiter 'Legal' / Seite 'Bildquellen'",
        norm="Lizenzgeber-Pflicht (z.B. CC-BY) — eigene Seite üblich",
    ),
    SectionPattern(
        section_id="haftungsausschluss",
        label="Haftungsausschluss / Disclaimer",
        heading_patterns=(
            re.compile(r"\bHaftungs(?:ausschluss|beschr(?:ä|ae)nkung|"
                         r"hinweis|begrenzung)",
                         re.IGNORECASE),
            re.compile(r"\bDisclaimer\b", re.IGNORECASE),
        ),
        category="recommended_separate",
        recommended_location="Footer-Reiter 'Legal' / Seite 'Disclaimer'",
        norm="BGB — Risikoabgrenzung gehört nicht ins § 5-TMG-Impressum",
    ),
    SectionPattern(
        section_id="nutzungsbedingungen",
        label="Nutzungsbedingungen",
        heading_patterns=(
            re.compile(r"\bNutzungsbedingungen\b", re.IGNORECASE),
            re.compile(r"\bTerms\s+of\s+Use\b", re.IGNORECASE),
        ),
        category="recommended_separate",
        recommended_location="Eigene Seite 'Nutzungsbedingungen' im Footer",
        norm="§§ 305 ff. BGB — eigene AGB-Seite üblich",
    ),
    SectionPattern(
        section_id="weee_elektrog",
        label="ElektroG / WEEE-Reg-Nr.",
        heading_patterns=(
            re.compile(
                r"(?:Elektro-?\s*und\s*Elektronikger(?:ä|ae)tegesetz|"
                r"\bElektroG\b|\bWEEE\b|"
                r"WEEE[\-\s]?Reg)",
                re.IGNORECASE,
            ),
        ),
        category="product_compliance",
        recommended_location=(
            "Eigene Seite 'Produktinformationen' oder Hinweis auf "
            "Produkt-/Recycling-Seite"
        ),
        norm="§ 6 Abs. 1 ElektroG — Pflichtkennzeichnung am Produkt, "
              "nicht zwingend im Impressum",
    ),
    SectionPattern(
        section_id="verpackg",
        label="VerpackG (Verpackungsregister)",
        heading_patterns=(
            re.compile(
                r"(?:Verpackungsgesetz|\bVerpackG\b|"
                r"LUCID[\-\s]?Reg|Verpackungs-?Reg)",
                re.IGNORECASE,
            ),
        ),
        category="product_compliance",
        recommended_location="Eigene Seite 'Produktinformationen'",
        norm="§ 7 VerpackG — Registrierung beim ZSVR",
    ),
    SectionPattern(
        section_id="battg",
        label="BattG (Batteriegesetz)",
        heading_patterns=(
            re.compile(
                r"(?:Batteriegesetz|\bBattG\b|"
                r"GRS-?Registrierung)",
                re.IGNORECASE,
            ),
        ),
        category="product_compliance",
        recommended_location="Eigene Seite 'Batterieinformationen'",
        norm="§ 4 BattG — Rücknahmepflicht",
    ),
    SectionPattern(
        section_id="aenderungsvorbehalt",
        label="Änderungsvorbehalt",
        heading_patterns=(
            re.compile(r"(?:Aenderungs|Änderungs)vorbehalt",
                         re.IGNORECASE),
            re.compile(r"\bbeh(?:ä|ae)lt\s+sich\s+vor", re.IGNORECASE),
        ),
        category="recommended_separate",
        recommended_location="In den Nutzungsbedingungen / Footer 'Legal'",
        norm="BGB-Anrede — gehört in AGB nicht ins Impressum",
    ),
)


def find_sections(text: str) -> list[tuple[SectionPattern, str]]:
    """Sucht im Text nach Sektions-Headings.

    Returns:
      Liste (SectionPattern, evidence_snippet) — pro gefundener Sektion.
    """
    if not text:
        return []
    hits: list[tuple[SectionPattern, str]] = []
    for sec in SECTIONS:
        for pat in sec.heading_patterns:
            m = pat.search(text)
            if m:
                snippet = text[max(0, m.start() - 20):m.end() + 80]
                snippet = " ".join(snippet.split())[:120]
                hits.append((sec, snippet))
                break  # eines reicht pro Sektion
    return hits
