from typing import List, Dict, Any, Optional
from datetime import datetime

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

from learning_units import (
    LearningUnit,
    LearningUnitCreate,
    LearningUnitUpdate,
    list_learning_units,
    get_learning_unit,
    create_learning_unit,
    update_learning_unit,
    delete_learning_unit,
)


router = APIRouter(
    prefix="/learning-units",
    tags=["learning-units"],
)


# ---------- Payload-Modelle für das Frontend ----------


class LearningUnitCreatePayload(BaseModel):
    """
    Payload so, wie er aus dem Frontend kommt:
    {
      "student": "...",
      "subject": "...",
      "title": "...",
      "grade": "7a"
    }
    """
    student: Optional[str] = None
    subject: Optional[str] = None
    title: Optional[str] = None
    grade: Optional[str] = None


class AttachWorksheetsPayload(BaseModel):
    worksheet_files: List[str]


class RemoveWorksheetPayload(BaseModel):
    worksheet_file: str


# ---------- Hilfsfunktion: Backend-Modell -> Frontend-Objekt ----------


def unit_to_frontend_dict(lu: LearningUnit) -> Dict[str, Any]:
    """
    Wandelt eine LearningUnit in das Format um, das das Frontend erwartet.
    Wichtig sind:
    - id
    - label  (sichtbarer Name)
    - meta   (Untertitelzeile)
    - worksheet_files (Liste von Dateinamen)
    """
    label = lu.title or "Lerneinheit"

    # Meta-Text: z.B. "Thema: Auge · Klasse: 7a · angelegt am 10.12.2025"
    meta_parts: List[str] = []
    if lu.topic:
        meta_parts.append(f"Thema: {lu.topic}")
    if lu.grade_level:
        meta_parts.append(f"Klasse: {lu.grade_level}")
    created_str = lu.created_at.strftime("%d.%m.%Y")
    meta_parts.append(f"angelegt am {created_str}")

    meta = " · ".join(meta_parts)

    return {
        "id": lu.id,
        "label": label,
        "meta": meta,
        "title": lu.title,
        "topic": lu.topic,
        "grade_level": lu.grade_level,
        "language": lu.language,
        "status": lu.status,
        "worksheet_files": lu.worksheet_files,
        "created_at": lu.created_at.isoformat(),
        "updated_at": lu.updated_at.isoformat(),
    }


# ---------- Endpunkte ----------


@router.get("/", response_model=List[Dict[str, Any]])
def api_list_learning_units():
    """Alle Lerneinheiten für das Frontend auflisten."""
    units = list_learning_units()
    return [unit_to_frontend_dict(u) for u in units]


@router.post("/", response_model=Dict[str, Any])
def api_create_learning_unit(payload: LearningUnitCreatePayload):
    """
    Neue Lerneinheit anlegen.
    Mapped das Frontend-Payload (student/subject/title/grade)
    auf das generische LearningUnit-Modell.
    """

    # Mindestens eines der Felder muss gesetzt sein
    if not (payload.student or payload.subject or payload.title):
        raise HTTPException(
            status_code=400,
            detail="Bitte mindestens Schüler/in, Fach oder Thema angeben.",
        )

    # Titel/Topic bestimmen
    # sichtbarer Titel: bevorzugt Thema (title), sonst Kombination
    if payload.title:
        title = payload.title
    else:
        parts = []
        if payload.subject:
            parts.append(payload.subject)
        if payload.student:
            parts.append(payload.student)
        title = " – ".join(parts) if parts else "Lerneinheit"

    topic = payload.title or payload.subject or None
    grade_level = payload.grade or None

    lu_create = LearningUnitCreate(
        title=title,
        description=None,
        topic=topic,
        grade_level=grade_level,
        language="de",
        worksheet_files=[],
        status="raw",
    )

    lu = create_learning_unit(lu_create)
    return unit_to_frontend_dict(lu)


@router.post("/{unit_id}/attach-worksheets", response_model=Dict[str, Any])
def api_attach_worksheets(unit_id: str, payload: AttachWorksheetsPayload):
    """
    Fügt der Lerneinheit eine oder mehrere Arbeitsblätter hinzu.
    """
    lu = get_learning_unit(unit_id)
    if not lu:
        raise HTTPException(status_code=404, detail="Lerneinheit nicht gefunden.")

    files_to_add = [f for f in payload.worksheet_files if f not in lu.worksheet_files]
    if files_to_add:
        new_list = lu.worksheet_files + files_to_add
        update = LearningUnitUpdate(worksheet_files=new_list)
        lu = update_learning_unit(unit_id, update)
        if not lu:
            raise HTTPException(status_code=500, detail="Lerneinheit konnte nicht aktualisiert werden.")

    return unit_to_frontend_dict(lu)


@router.post("/{unit_id}/remove-worksheet", response_model=Dict[str, Any])
def api_remove_worksheet(unit_id: str, payload: RemoveWorksheetPayload):
    """
    Entfernt genau ein Arbeitsblatt aus der Lerneinheit.
    """
    lu = get_learning_unit(unit_id)
    if not lu:
        raise HTTPException(status_code=404, detail="Lerneinheit nicht gefunden.")

    if payload.worksheet_file not in lu.worksheet_files:
        # Nichts zu tun, aber kein Fehler – einfach unverändert zurückgeben
        return unit_to_frontend_dict(lu)

    new_list = [f for f in lu.worksheet_files if f != payload.worksheet_file]
    update = LearningUnitUpdate(worksheet_files=new_list)
    lu = update_learning_unit(unit_id, update)
    if not lu:
        raise HTTPException(status_code=500, detail="Lerneinheit konnte nicht aktualisiert werden.")

    return unit_to_frontend_dict(lu)


@router.delete("/{unit_id}")
def api_delete_learning_unit(unit_id: str):
    """
    Lerneinheit komplett löschen (aktuell vom Frontend noch nicht verwendet).
    """
    ok = delete_learning_unit(unit_id)
    if not ok:
        raise HTTPException(status_code=404, detail="Lerneinheit nicht gefunden.")
    return {"status": "deleted", "id": unit_id}

