"""
Abitur Document Store API - Verwaltung von Abitur-Aufgaben und Erwartungshorizonten.

Unterstützt:
- Bundesland-spezifische Dokumente
- Fach, Jahr, Niveau (eA/gA), Aufgabennummer
- KI-basierte Dokumentenerkennung
- RAG-Integration mit Vector Store

Dateinamen-Schema (NiBiS Niedersachsen):
- 2025_Deutsch_eA_I.pdf - Aufgabe
- 2025_Deutsch_eA_I_EWH.pdf - Erwartungshorizont
"""

import logging
import uuid
import os
import re
import zipfile
import tempfile
from datetime import datetime
from typing import List, Dict, Any, Optional
from enum import Enum
from pathlib import Path
from dataclasses import dataclass

from fastapi import APIRouter, HTTPException, UploadFile, File, Form, BackgroundTasks
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/abitur-docs",
    tags=["abitur-docs"],
)

# Storage directory
DOCS_DIR = Path("/tmp/abitur-docs")
DOCS_DIR.mkdir(parents=True, exist_ok=True)


# ============================================================================
# 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"  # Betriebswirtschaft mit Rechnungswesen
    BVW = "bvw"  # Volkswirtschaft
    ERNAEHRUNG = "ernaehrung"
    MECHATRONIK = "mechatronik"
    GESUNDHEIT_PFLEGE = "gesundheit_pflege"
    PAEDAGOGIK_PSYCHOLOGIE = "paedagogik_psychologie"


class Niveau(str, Enum):
    """Anforderungsniveau."""
    EA = "eA"  # Erhöhtes Anforderungsniveau (Leistungskurs)
    GA = "gA"  # Grundlegendes Anforderungsniveau (Grundkurs)


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


class VerarbeitungsStatus(str, Enum):
    """Status der Dokumentenverarbeitung."""
    PENDING = "pending"
    PROCESSING = "processing"
    RECOGNIZED = "recognized"  # KI hat Metadaten erkannt
    CONFIRMED = "confirmed"  # Entwickler hat bestätigt
    INDEXED = "indexed"  # Im Vector Store
    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  # I, II, III, 1, 2, etc.


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  # Erkennungs-Confidence
    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


# ============================================================================
# In-Memory Storage
# ============================================================================

_dokumente: Dict[str, AbiturDokument] = {}


# ============================================================================
# Helper Functions - Dokumentenerkennung
# ============================================================================

def parse_nibis_filename(filename: str) -> RecognitionResult:
    """
    Erkennt Metadaten aus NiBiS-Dateinamen.

    Beispiele:
    - 2025_Deutsch_eA_I.pdf
    - 2025_Deutsch_eA_I_EWH.pdf
    - 2025_Biologie_gA_1.pdf
    - 2025_Englisch_eA_HV.pdf (Hörverstehen)
    """
    result = RecognitionResult(
        success=False,
        bundesland=Bundesland.NIEDERSACHSEN,  # NiBiS = Niedersachsen
        fach=None,
        jahr=None,
        niveau=None,
        typ=None,
        aufgaben_nummer=None,
        confidence=0.0,
        raw_filename=filename,
        suggestions=[]
    )

    # Bereinige Dateiname
    name = Path(filename).stem.lower()

    # Extrahiere Jahr (4 Ziffern am Anfang)
    jahr_match = re.match(r'^(\d{4})', name)
    if jahr_match:
        result.jahr = int(jahr_match.group(1))
        result.confidence += 0.2

    # Extrahiere Fach
    for fach_key, fach_enum in FACH_NAME_MAPPING.items():
        if fach_key in name.replace("_", "").replace("-", ""):
            result.fach = fach_enum
            result.confidence += 0.3
            break

    # Extrahiere Niveau (eA/gA)
    if "_ea" in name or "_ea_" in name or "ea_" in name:
        result.niveau = Niveau.EA
        result.confidence += 0.2
    elif "_ga" in name or "_ga_" in name or "ga_" in name:
        result.niveau = Niveau.GA
        result.confidence += 0.2

    # Extrahiere Typ
    if "_ewh" in name:
        result.typ = DokumentTyp.ERWARTUNGSHORIZONT
        result.confidence += 0.2
    elif "_hv" in name or "hoerverstehen" in name:
        result.typ = DokumentTyp.HOERVERSTEHEN
        result.confidence += 0.15
    elif "_sm" in name or "_me" in name or "sprachmittlung" in name:
        result.typ = DokumentTyp.SPRACHMITTLUNG
        result.confidence += 0.15
    elif "deckblatt" in name:
        result.typ = DokumentTyp.DECKBLATT
        result.confidence += 0.15
    elif "material" in name:
        result.typ = DokumentTyp.MATERIAL
        result.confidence += 0.15
    elif "bewertung" in name:
        result.typ = DokumentTyp.BEWERTUNGSBOGEN
        result.confidence += 0.15
    else:
        result.typ = DokumentTyp.AUFGABE
        result.confidence += 0.1

    # Extrahiere Aufgabennummer (römisch oder arabisch)
    aufgabe_match = re.search(r'_([ivx]+|[1-4][abc]?)(?:_|\.pdf|$)', name, re.IGNORECASE)
    if aufgabe_match:
        result.aufgaben_nummer = aufgabe_match.group(1).upper()
        result.confidence += 0.1

    # Erfolg wenn mindestens Fach und Jahr erkannt
    if result.fach and result.jahr:
        result.success = True

    # Normalisiere Confidence auf max 1.0
    result.confidence = min(result.confidence, 1.0)

    return result


def _to_dokument_response(doc: AbiturDokument) -> DokumentResponse:
    """Konvertiert internes Dokument zu Response."""
    return DokumentResponse(
        id=doc.id,
        dateiname=doc.dateiname,
        original_dateiname=doc.original_dateiname,
        bundesland=doc.bundesland,
        fach=doc.fach,
        jahr=doc.jahr,
        niveau=doc.niveau,
        typ=doc.typ,
        aufgaben_nummer=doc.aufgaben_nummer,
        status=doc.status,
        confidence=doc.confidence,
        file_path=doc.file_path,
        file_size=doc.file_size,
        indexed=doc.indexed,
        vector_ids=doc.vector_ids,
        created_at=doc.created_at,
        updated_at=doc.updated_at
    )


# ============================================================================
# API Endpoints - Dokumente
# ============================================================================

@router.post("/upload", response_model=DokumentResponse)
async def upload_dokument(
    file: UploadFile = File(...),
    bundesland: Optional[Bundesland] = Form(None),
    fach: Optional[Fach] = Form(None),
    jahr: Optional[int] = Form(None),
    niveau: Optional[Niveau] = Form(None),
    typ: Optional[DokumentTyp] = Form(None),
    aufgaben_nummer: Optional[str] = Form(None)
):
    """
    Lädt ein einzelnes Dokument hoch.

    Metadaten können manuell angegeben oder automatisch erkannt werden.
    """
    if not file.filename:
        raise HTTPException(status_code=400, detail="Kein Dateiname")

    # Erkenne Metadaten aus Dateiname
    recognition = parse_nibis_filename(file.filename)

    # Überschreibe mit manuellen Angaben
    final_bundesland = bundesland or recognition.bundesland or Bundesland.NIEDERSACHSEN
    final_fach = fach or recognition.fach
    final_jahr = jahr or recognition.jahr or datetime.now().year
    final_niveau = niveau or recognition.niveau or Niveau.EA
    final_typ = typ or recognition.typ or DokumentTyp.AUFGABE
    final_aufgabe = aufgaben_nummer or recognition.aufgaben_nummer

    if not final_fach:
        raise HTTPException(status_code=400, detail="Fach konnte nicht erkannt werden")

    # Generiere ID und speichere Datei
    doc_id = str(uuid.uuid4())
    file_ext = Path(file.filename).suffix
    safe_filename = f"{doc_id}{file_ext}"
    file_path = DOCS_DIR / safe_filename

    content = await file.read()
    with open(file_path, "wb") as f:
        f.write(content)

    now = datetime.utcnow()

    dokument = AbiturDokument(
        id=doc_id,
        dateiname=safe_filename,
        original_dateiname=file.filename,
        bundesland=final_bundesland,
        fach=final_fach,
        jahr=final_jahr,
        niveau=final_niveau,
        typ=final_typ,
        aufgaben_nummer=final_aufgabe,
        status=VerarbeitungsStatus.RECOGNIZED if recognition.success else VerarbeitungsStatus.PENDING,
        confidence=recognition.confidence,
        file_path=str(file_path),
        file_size=len(content),
        indexed=False,
        vector_ids=[],
        created_at=now,
        updated_at=now
    )

    _dokumente[doc_id] = dokument
    logger.info(f"Uploaded document {doc_id}: {file.filename}")

    return _to_dokument_response(dokument)


@router.post("/import-zip", response_model=ImportResult)
async def import_zip(
    file: UploadFile = File(...),
    bundesland: Bundesland = Form(Bundesland.NIEDERSACHSEN),
    background_tasks: BackgroundTasks = None
):
    """
    Importiert alle PDFs aus einer ZIP-Datei.

    Erkennt automatisch Metadaten aus Dateinamen.
    """
    if not file.filename or not file.filename.endswith(".zip"):
        raise HTTPException(status_code=400, detail="ZIP-Datei erforderlich")

    # Speichere ZIP temporär
    with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as tmp:
        content = await file.read()
        tmp.write(content)
        tmp_path = tmp.name

    documents = []
    total = 0
    recognized = 0
    errors = 0

    try:
        with zipfile.ZipFile(tmp_path, 'r') as zip_ref:
            for zip_info in zip_ref.infolist():
                # Nur PDFs
                if not zip_info.filename.lower().endswith(".pdf"):
                    continue

                # Ignoriere Mac-spezifische Dateien
                if "__MACOSX" in zip_info.filename or zip_info.filename.startswith("."):
                    continue

                # Ignoriere Thumbs.db
                if "thumbs.db" in zip_info.filename.lower():
                    continue

                total += 1

                try:
                    # Erkenne Metadaten
                    basename = Path(zip_info.filename).name
                    recognition = parse_nibis_filename(basename)

                    if not recognition.fach:
                        errors += 1
                        logger.warning(f"Konnte Fach nicht erkennen: {basename}")
                        continue

                    # Extrahiere und speichere
                    doc_id = str(uuid.uuid4())
                    file_ext = Path(basename).suffix
                    safe_filename = f"{doc_id}{file_ext}"
                    file_path = DOCS_DIR / safe_filename

                    with zip_ref.open(zip_info.filename) as source:
                        file_content = source.read()
                        with open(file_path, "wb") as target:
                            target.write(file_content)

                    now = datetime.utcnow()

                    dokument = AbiturDokument(
                        id=doc_id,
                        dateiname=safe_filename,
                        original_dateiname=basename,
                        bundesland=bundesland,
                        fach=recognition.fach,
                        jahr=recognition.jahr or datetime.now().year,
                        niveau=recognition.niveau or Niveau.EA,
                        typ=recognition.typ or DokumentTyp.AUFGABE,
                        aufgaben_nummer=recognition.aufgaben_nummer,
                        status=VerarbeitungsStatus.RECOGNIZED,
                        confidence=recognition.confidence,
                        file_path=str(file_path),
                        file_size=len(file_content),
                        indexed=False,
                        vector_ids=[],
                        created_at=now,
                        updated_at=now
                    )

                    _dokumente[doc_id] = dokument
                    documents.append(_to_dokument_response(dokument))
                    recognized += 1

                except Exception as e:
                    errors += 1
                    logger.error(f"Fehler bei {zip_info.filename}: {e}")

    finally:
        # Lösche temporäre ZIP
        os.unlink(tmp_path)

    logger.info(f"ZIP-Import: {recognized}/{total} erkannt, {errors} Fehler")

    return ImportResult(
        total_files=total,
        recognized=recognized,
        errors=errors,
        documents=documents
    )


@router.get("/", response_model=List[DokumentResponse])
async def list_dokumente(
    bundesland: Optional[Bundesland] = None,
    fach: Optional[Fach] = None,
    jahr: Optional[int] = None,
    niveau: Optional[Niveau] = None,
    typ: Optional[DokumentTyp] = None,
    status: Optional[VerarbeitungsStatus] = None,
    indexed: Optional[bool] = None
):
    """Listet Dokumente mit optionalen Filtern."""
    docs = list(_dokumente.values())

    if bundesland:
        docs = [d for d in docs if d.bundesland == bundesland]
    if fach:
        docs = [d for d in docs if d.fach == fach]
    if jahr:
        docs = [d for d in docs if d.jahr == jahr]
    if niveau:
        docs = [d for d in docs if d.niveau == niveau]
    if typ:
        docs = [d for d in docs if d.typ == typ]
    if status:
        docs = [d for d in docs if d.status == status]
    if indexed is not None:
        docs = [d for d in docs if d.indexed == indexed]

    docs.sort(key=lambda x: (x.jahr, x.fach.value, x.niveau.value), reverse=True)
    return [_to_dokument_response(d) for d in docs]


@router.get("/{doc_id}", response_model=DokumentResponse)
async def get_dokument(doc_id: str):
    """Ruft ein Dokument ab."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")
    return _to_dokument_response(doc)


@router.put("/{doc_id}", response_model=DokumentResponse)
async def update_dokument(doc_id: str, data: DokumentUpdate):
    """Aktualisiert Dokument-Metadaten (nach KI-Erkennung durch Entwickler)."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")

    if data.bundesland is not None:
        doc.bundesland = data.bundesland
    if data.fach is not None:
        doc.fach = data.fach
    if data.jahr is not None:
        doc.jahr = data.jahr
    if data.niveau is not None:
        doc.niveau = data.niveau
    if data.typ is not None:
        doc.typ = data.typ
    if data.aufgaben_nummer is not None:
        doc.aufgaben_nummer = data.aufgaben_nummer
    if data.status is not None:
        doc.status = data.status

    doc.updated_at = datetime.utcnow()

    return _to_dokument_response(doc)


@router.post("/{doc_id}/confirm", response_model=DokumentResponse)
async def confirm_dokument(doc_id: str):
    """Bestätigt erkannte Metadaten."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")

    doc.status = VerarbeitungsStatus.CONFIRMED
    doc.updated_at = datetime.utcnow()

    return _to_dokument_response(doc)


@router.post("/{doc_id}/index", response_model=DokumentResponse)
async def index_dokument(doc_id: str):
    """Indiziert Dokument im Vector Store."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")

    if doc.status not in [VerarbeitungsStatus.CONFIRMED, VerarbeitungsStatus.RECOGNIZED]:
        raise HTTPException(status_code=400, detail="Dokument muss erst bestätigt werden")

    # TODO: Vector Store Integration
    # 1. PDF lesen und Text extrahieren
    # 2. In Chunks aufteilen
    # 3. Embeddings generieren
    # 4. Mit Metadaten im Vector Store speichern

    # Demo: Simuliere Indexierung
    doc.indexed = True
    doc.vector_ids = [f"vec_{doc_id}_{i}" for i in range(3)]  # Demo-IDs
    doc.status = VerarbeitungsStatus.INDEXED
    doc.updated_at = datetime.utcnow()

    logger.info(f"Document {doc_id} indexed (demo)")

    return _to_dokument_response(doc)


@router.delete("/{doc_id}")
async def delete_dokument(doc_id: str):
    """Löscht ein Dokument."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")

    # Lösche Datei
    if os.path.exists(doc.file_path):
        os.remove(doc.file_path)

    # TODO: Aus Vector Store entfernen

    del _dokumente[doc_id]

    return {"status": "deleted", "id": doc_id}


@router.get("/{doc_id}/download")
async def download_dokument(doc_id: str):
    """Lädt Dokument herunter."""
    doc = _dokumente.get(doc_id)
    if not doc:
        raise HTTPException(status_code=404, detail="Dokument nicht gefunden")

    if not os.path.exists(doc.file_path):
        raise HTTPException(status_code=404, detail="Datei nicht gefunden")

    return FileResponse(
        doc.file_path,
        filename=doc.original_dateiname,
        media_type="application/pdf"
    )


# ============================================================================
# API Endpoints - Erkennung
# ============================================================================

@router.post("/recognize", response_model=RecognitionResult)
async def recognize_filename(filename: str):
    """Erkennt Metadaten aus einem Dateinamen."""
    return parse_nibis_filename(filename)


@router.post("/bulk-confirm")
async def bulk_confirm(doc_ids: List[str]):
    """Bestätigt mehrere Dokumente auf einmal."""
    confirmed = 0
    for doc_id in doc_ids:
        doc = _dokumente.get(doc_id)
        if doc and doc.status == VerarbeitungsStatus.RECOGNIZED:
            doc.status = VerarbeitungsStatus.CONFIRMED
            doc.updated_at = datetime.utcnow()
            confirmed += 1

    return {"confirmed": confirmed, "total": len(doc_ids)}


@router.post("/bulk-index")
async def bulk_index(doc_ids: List[str]):
    """Indiziert mehrere Dokumente auf einmal."""
    indexed = 0
    for doc_id in doc_ids:
        doc = _dokumente.get(doc_id)
        if doc and doc.status in [VerarbeitungsStatus.CONFIRMED, VerarbeitungsStatus.RECOGNIZED]:
            # Demo-Indexierung
            doc.indexed = True
            doc.vector_ids = [f"vec_{doc_id}_{i}" for i in range(3)]
            doc.status = VerarbeitungsStatus.INDEXED
            doc.updated_at = datetime.utcnow()
            indexed += 1

    return {"indexed": indexed, "total": len(doc_ids)}


# ============================================================================
# API Endpoints - Statistiken
# ============================================================================

@router.get("/stats/overview")
async def get_stats_overview():
    """Gibt Übersicht über alle Dokumente."""
    docs = list(_dokumente.values())

    by_bundesland = {}
    by_fach = {}
    by_jahr = {}
    by_status = {}

    for doc in docs:
        by_bundesland[doc.bundesland.value] = by_bundesland.get(doc.bundesland.value, 0) + 1
        by_fach[doc.fach.value] = by_fach.get(doc.fach.value, 0) + 1
        by_jahr[doc.jahr] = by_jahr.get(doc.jahr, 0) + 1
        by_status[doc.status.value] = by_status.get(doc.status.value, 0) + 1

    return {
        "total": len(docs),
        "indexed": sum(1 for d in docs if d.indexed),
        "pending": sum(1 for d in docs if d.status == VerarbeitungsStatus.PENDING),
        "by_bundesland": by_bundesland,
        "by_fach": by_fach,
        "by_jahr": by_jahr,
        "by_status": by_status
    }


# ============================================================================
# API Endpoints - Suche (für Klausur-Korrektur)
# ============================================================================

@router.get("/search", response_model=List[DokumentResponse])
async def search_dokumente(
    bundesland: Bundesland,
    fach: Fach,
    jahr: Optional[int] = None,
    niveau: Optional[Niveau] = None,
    nur_indexed: bool = True
):
    """
    Sucht Dokumente für Klausur-Korrektur.

    Gibt nur indizierte Dokumente zurück (Standard).
    """
    docs = list(_dokumente.values())

    # Pflichtfilter
    docs = [d for d in docs if d.bundesland == bundesland and d.fach == fach]

    # Optionale Filter
    if jahr:
        docs = [d for d in docs if d.jahr == jahr]
    if niveau:
        docs = [d for d in docs if d.niveau == niveau]
    if nur_indexed:
        docs = [d for d in docs if d.indexed]

    # Sortiere: Aufgaben vor Erwartungshorizonten
    aufgaben = [d for d in docs if d.typ == DokumentTyp.AUFGABE]
    ewh = [d for d in docs if d.typ == DokumentTyp.ERWARTUNGSHORIZONT]
    andere = [d for d in docs if d.typ not in [DokumentTyp.AUFGABE, DokumentTyp.ERWARTUNGSHORIZONT]]

    result = []
    for aufgabe in aufgaben:
        result.append(_to_dokument_response(aufgabe))
        # Finde passenden EWH
        matching_ewh = next(
            (e for e in ewh
             if e.jahr == aufgabe.jahr
             and e.niveau == aufgabe.niveau
             and e.aufgaben_nummer == aufgabe.aufgaben_nummer),
            None
        )
        if matching_ewh:
            result.append(_to_dokument_response(matching_ewh))

    # Restliche EWH und andere
    for e in ewh:
        if _to_dokument_response(e) not in result:
            result.append(_to_dokument_response(e))
    for a in andere:
        result.append(_to_dokument_response(a))

    return result


# ============================================================================
# Enums Endpoint (für Frontend)
# ============================================================================

@router.get("/enums/bundeslaender")
async def get_bundeslaender():
    """Gibt alle Bundesländer zurück."""
    return [{"value": b.value, "label": b.value.replace("_", " ").title()} for b in Bundesland]


@router.get("/enums/faecher")
async def get_faecher():
    """Gibt alle Fächer zurück."""
    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",
    }
    return [{"value": f.value, "label": labels.get(f, f.value)} for f in Fach]


@router.get("/enums/niveaus")
async def get_niveaus():
    """Gibt alle Niveaus zurück."""
    return [
        {"value": "eA", "label": "eA (erhöhtes Anforderungsniveau)"},
        {"value": "gA", "label": "gA (grundlegendes Anforderungsniveau)"}
    ]


@router.get("/enums/typen")
async def get_typen():
    """Gibt alle Dokumenttypen zurück."""
    labels = {
        DokumentTyp.AUFGABE: "Aufgabe",
        DokumentTyp.ERWARTUNGSHORIZONT: "Erwartungshorizont",
        DokumentTyp.DECKBLATT: "Deckblatt",
        DokumentTyp.MATERIAL: "Material",
        DokumentTyp.HOERVERSTEHEN: "Hörverstehen",
        DokumentTyp.SPRACHMITTLUNG: "Sprachmittlung",
        DokumentTyp.BEWERTUNGSBOGEN: "Bewertungsbogen",
    }
    return [{"value": t.value, "label": labels.get(t, t.value)} for t in DokumentTyp]


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


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


# Backwards-compatible AbiturDokument for tests (different from internal dataclass)
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
