"""
Abitur Document Store - Enums, Pydantic Models, Data Classes.

Shared types for abitur_docs_api and abitur_docs_recognition.
"""

from datetime import datetime
from typing import List, Dict, Any, Optional
from enum import Enum
from dataclasses import dataclass

from pydantic import BaseModel, Field


# ============================================================================
# Enums
# ============================================================================

class Bundesland(str, Enum):
    """Bundesländer mit Zentralabitur."""
    NIEDERSACHSEN = "niedersachsen"
    BAYERN = "bayern"
    BADEN_WUERTTEMBERG = "baden_wuerttemberg"
    NORDRHEIN_WESTFALEN = "nordrhein_westfalen"
    HESSEN = "hessen"
    SACHSEN = "sachsen"
    THUERINGEN = "thueringen"
    BERLIN = "berlin"
    HAMBURG = "hamburg"
    SCHLESWIG_HOLSTEIN = "schleswig_holstein"
    BREMEN = "bremen"
    BRANDENBURG = "brandenburg"
    MECKLENBURG_VORPOMMERN = "mecklenburg_vorpommern"
    SACHSEN_ANHALT = "sachsen_anhalt"
    RHEINLAND_PFALZ = "rheinland_pfalz"
    SAARLAND = "saarland"


class Fach(str, Enum):
    """Abiturfächer."""
    DEUTSCH = "deutsch"
    ENGLISCH = "englisch"
    MATHEMATIK = "mathematik"
    BIOLOGIE = "biologie"
    CHEMIE = "chemie"
    PHYSIK = "physik"
    GESCHICHTE = "geschichte"
    ERDKUNDE = "erdkunde"
    POLITIK_WIRTSCHAFT = "politik_wirtschaft"
    FRANZOESISCH = "franzoesisch"
    SPANISCH = "spanisch"
    LATEIN = "latein"
    GRIECHISCH = "griechisch"
    KUNST = "kunst"
    MUSIK = "musik"
    SPORT = "sport"
    INFORMATIK = "informatik"
    EV_RELIGION = "ev_religion"
    KATH_RELIGION = "kath_religion"
    WERTE_NORMEN = "werte_normen"
    BRC = "brc"
    BVW = "bvw"
    ERNAEHRUNG = "ernaehrung"
    MECHATRONIK = "mechatronik"
    GESUNDHEIT_PFLEGE = "gesundheit_pflege"
    PAEDAGOGIK_PSYCHOLOGIE = "paedagogik_psychologie"


class Niveau(str, Enum):
    """Anforderungsniveau."""
    EA = "eA"
    GA = "gA"


class DokumentTyp(str, Enum):
    """Dokumenttyp."""
    AUFGABE = "aufgabe"
    ERWARTUNGSHORIZONT = "erwartungshorizont"
    DECKBLATT = "deckblatt"
    MATERIAL = "material"
    HOERVERSTEHEN = "hoerverstehen"
    SPRACHMITTLUNG = "sprachmittlung"
    BEWERTUNGSBOGEN = "bewertungsbogen"


class VerarbeitungsStatus(str, Enum):
    """Status der Dokumentenverarbeitung."""
    PENDING = "pending"
    PROCESSING = "processing"
    RECOGNIZED = "recognized"
    CONFIRMED = "confirmed"
    INDEXED = "indexed"
    ERROR = "error"


# ============================================================================
# Fach-Mapping für Dateinamen
# ============================================================================

FACH_NAME_MAPPING = {
    "deutsch": Fach.DEUTSCH,
    "englisch": Fach.ENGLISCH,
    "mathe": Fach.MATHEMATIK,
    "mathematik": Fach.MATHEMATIK,
    "biologie": Fach.BIOLOGIE,
    "bio": Fach.BIOLOGIE,
    "chemie": Fach.CHEMIE,
    "physik": Fach.PHYSIK,
    "geschichte": Fach.GESCHICHTE,
    "erdkunde": Fach.ERDKUNDE,
    "geographie": Fach.ERDKUNDE,
    "politikwirtschaft": Fach.POLITIK_WIRTSCHAFT,
    "politik": Fach.POLITIK_WIRTSCHAFT,
    "franzoesisch": Fach.FRANZOESISCH,
    "franz": Fach.FRANZOESISCH,
    "spanisch": Fach.SPANISCH,
    "latein": Fach.LATEIN,
    "griechisch": Fach.GRIECHISCH,
    "kunst": Fach.KUNST,
    "musik": Fach.MUSIK,
    "sport": Fach.SPORT,
    "informatik": Fach.INFORMATIK,
    "evreligion": Fach.EV_RELIGION,
    "kathreligion": Fach.KATH_RELIGION,
    "wertenormen": Fach.WERTE_NORMEN,
    "brc": Fach.BRC,
    "bvw": Fach.BVW,
    "ernaehrung": Fach.ERNAEHRUNG,
    "mecha": Fach.MECHATRONIK,
    "mechatronik": Fach.MECHATRONIK,
    "technikmecha": Fach.MECHATRONIK,
    "gespfl": Fach.GESUNDHEIT_PFLEGE,
    "paedpsych": Fach.PAEDAGOGIK_PSYCHOLOGIE,
}


# ============================================================================
# Pydantic Models
# ============================================================================

class DokumentCreate(BaseModel):
    """Manuelles Erstellen eines Dokuments."""
    bundesland: Bundesland
    fach: Fach
    jahr: int = Field(ge=2000, le=2100)
    niveau: Niveau
    typ: DokumentTyp
    aufgaben_nummer: Optional[str] = None


class DokumentUpdate(BaseModel):
    """Update für erkannte Metadaten."""
    bundesland: Optional[Bundesland] = None
    fach: Optional[Fach] = None
    jahr: Optional[int] = None
    niveau: Optional[Niveau] = None
    typ: Optional[DokumentTyp] = None
    aufgaben_nummer: Optional[str] = None
    status: Optional[VerarbeitungsStatus] = None


class DokumentResponse(BaseModel):
    """Response für ein Dokument."""
    id: str
    dateiname: str
    original_dateiname: str
    bundesland: Bundesland
    fach: Fach
    jahr: int
    niveau: Niveau
    typ: DokumentTyp
    aufgaben_nummer: Optional[str]
    status: VerarbeitungsStatus
    confidence: float
    file_path: str
    file_size: int
    indexed: bool
    vector_ids: List[str]
    created_at: datetime
    updated_at: datetime


class ImportResult(BaseModel):
    """Ergebnis eines ZIP-Imports."""
    total_files: int
    recognized: int
    errors: int
    documents: List[DokumentResponse]


class RecognitionResult(BaseModel):
    """Ergebnis der Dokumentenerkennung."""
    success: bool
    bundesland: Optional[Bundesland]
    fach: Optional[Fach]
    jahr: Optional[int]
    niveau: Optional[Niveau]
    typ: Optional[DokumentTyp]
    aufgaben_nummer: Optional[str]
    confidence: float
    raw_filename: str
    suggestions: List[Dict[str, Any]]

    @property
    def extracted(self) -> Dict[str, Any]:
        """Backwards-compatible property returning extracted values as dict."""
        result = {}
        if self.bundesland:
            result["bundesland"] = self.bundesland.value
        if self.fach:
            result["fach"] = self.fach.value
        if self.jahr:
            result["jahr"] = self.jahr
        if self.niveau:
            result["niveau"] = self.niveau.value
        if self.typ:
            result["typ"] = self.typ.value
        if self.aufgaben_nummer:
            result["aufgaben_nummer"] = self.aufgaben_nummer
        return result

    @property
    def method(self) -> str:
        """Backwards-compatible property for recognition method."""
        return "filename_pattern"


# ============================================================================
# Internal Data Classes
# ============================================================================

@dataclass
class AbiturDokument:
    """Internes Dokument."""
    id: str
    dateiname: str
    original_dateiname: str
    bundesland: Bundesland
    fach: Fach
    jahr: int
    niveau: Niveau
    typ: DokumentTyp
    aufgaben_nummer: Optional[str]
    status: VerarbeitungsStatus
    confidence: float
    file_path: str
    file_size: int
    indexed: bool
    vector_ids: List[str]
    created_at: datetime
    updated_at: datetime


# ============================================================================
# Backwards-compatibility aliases (used by tests)
# ============================================================================
AbiturFach = Fach
Anforderungsniveau = Niveau


class DocumentMetadata(BaseModel):
    """Backwards-compatible metadata model for tests."""
    jahr: Optional[int] = None
    bundesland: Optional[str] = None
    fach: Optional[str] = None
    niveau: Optional[str] = None
    dokument_typ: Optional[str] = None
    aufgaben_nummer: Optional[str] = None


class AbiturDokumentCompat(BaseModel):
    """Backwards-compatible AbiturDokument model for tests."""
    id: str
    filename: str
    file_path: str
    metadata: DocumentMetadata
    status: VerarbeitungsStatus
    recognition_result: Optional[RecognitionResult] = None
    created_at: datetime
    updated_at: datetime

    class Config:
        arbitrary_types_allowed = True


# ============================================================================
# Fach Labels (für Frontend Enum-Endpoint)
# ============================================================================

FACH_LABELS = {
    Fach.DEUTSCH: "Deutsch",
    Fach.ENGLISCH: "Englisch",
    Fach.MATHEMATIK: "Mathematik",
    Fach.BIOLOGIE: "Biologie",
    Fach.CHEMIE: "Chemie",
    Fach.PHYSIK: "Physik",
    Fach.GESCHICHTE: "Geschichte",
    Fach.ERDKUNDE: "Erdkunde",
    Fach.POLITIK_WIRTSCHAFT: "Politik-Wirtschaft",
    Fach.FRANZOESISCH: "Französisch",
    Fach.SPANISCH: "Spanisch",
    Fach.LATEIN: "Latein",
    Fach.GRIECHISCH: "Griechisch",
    Fach.KUNST: "Kunst",
    Fach.MUSIK: "Musik",
    Fach.SPORT: "Sport",
    Fach.INFORMATIK: "Informatik",
    Fach.EV_RELIGION: "Ev. Religion",
    Fach.KATH_RELIGION: "Kath. Religion",
    Fach.WERTE_NORMEN: "Werte und Normen",
    Fach.BRC: "BRC (Betriebswirtschaft)",
    Fach.BVW: "BVW (Volkswirtschaft)",
    Fach.ERNAEHRUNG: "Ernährung",
    Fach.MECHATRONIK: "Mechatronik",
    Fach.GESUNDHEIT_PFLEGE: "Gesundheit-Pflege",
    Fach.PAEDAGOGIK_PSYCHOLOGIE: "Pädagogik-Psychologie",
}

DOKUMENT_TYP_LABELS = {
    DokumentTyp.AUFGABE: "Aufgabe",
    DokumentTyp.ERWARTUNGSHORIZONT: "Erwartungshorizont",
    DokumentTyp.DECKBLATT: "Deckblatt",
    DokumentTyp.MATERIAL: "Material",
    DokumentTyp.HOERVERSTEHEN: "Hörverstehen",
    DokumentTyp.SPRACHMITTLUNG: "Sprachmittlung",
    DokumentTyp.BEWERTUNGSBOGEN: "Bewertungsbogen",
}
