"""
Classroom API - Template Routes

Lesson template management endpoints (Feature f37).
"""

from uuid import uuid4
from typing import Dict, Optional, List
from datetime import datetime
import logging

from fastapi import APIRouter, HTTPException, Query

from classroom_engine import (
    LessonSession,
    LessonTemplate,
    SYSTEM_TEMPLATES,
    get_default_durations,
)

from ..models import (
    TemplateCreate,
    TemplateUpdate,
    TemplateResponse,
    TemplateListResponse,
)
from ..services.persistence import (
    sessions,
    init_db_if_needed,
    persist_session,
    DB_ENABLED,
    SessionLocal,
)
from .sessions import build_session_response, SessionResponse

logger = logging.getLogger(__name__)

router = APIRouter(tags=["Templates"])


def _build_template_response(template: LessonTemplate, is_system: bool = False) -> TemplateResponse:
    """Baut eine Template-Response."""
    return TemplateResponse(
        template_id=template.template_id,
        teacher_id=template.teacher_id,
        name=template.name,
        description=template.description,
        subject=template.subject,
        grade_level=template.grade_level,
        phase_durations=template.phase_durations,
        default_topic=template.default_topic,
        default_notes=template.default_notes,
        is_public=template.is_public,
        usage_count=template.usage_count,
        total_duration_minutes=sum(template.phase_durations.values()),
        created_at=template.created_at.isoformat() if template.created_at else None,
        updated_at=template.updated_at.isoformat() if template.updated_at else None,
        is_system_template=is_system,
    )


def _get_system_templates() -> List[TemplateResponse]:
    """Gibt die vordefinierten System-Templates zurueck."""
    templates = []
    for t in SYSTEM_TEMPLATES:
        template = LessonTemplate(
            template_id=t["template_id"],
            teacher_id="system",
            name=t["name"],
            description=t.get("description", ""),
            phase_durations=t["phase_durations"],
            is_public=True,
            usage_count=0,
        )
        templates.append(_build_template_response(template, is_system=True))
    return templates


@router.get("/templates", response_model=TemplateListResponse)
async def list_templates(
    teacher_id: Optional[str] = Query(None, description="Filter nach Lehrer"),
    subject: Optional[str] = Query(None, description="Filter nach Fach"),
    include_system: bool = Query(True, description="System-Vorlagen einbeziehen")
) -> TemplateListResponse:
    """
    Listet verfuegbare Stunden-Vorlagen (Feature f37).

    Ohne teacher_id werden nur oeffentliche und System-Vorlagen gezeigt.
    Mit teacher_id werden auch private Vorlagen des Lehrers angezeigt.
    """
    init_db_if_needed()

    templates: List[TemplateResponse] = []

    # System-Templates hinzufuegen
    if include_system:
        system_templates = _get_system_templates()
        templates.extend(system_templates)

    # DB-Templates laden wenn verfuegbar
    if DB_ENABLED:
        try:
            from classroom_engine.repository import TemplateRepository
            db = SessionLocal()
            repo = TemplateRepository(db)

            if subject:
                db_templates = repo.get_by_subject(subject, teacher_id)
            elif teacher_id:
                db_templates = repo.get_by_teacher(teacher_id, include_public=True)
            else:
                db_templates = repo.get_public_templates()

            for db_t in db_templates:
                template = repo.to_dataclass(db_t)
                templates.append(_build_template_response(template))

            db.close()
        except Exception as e:
            logger.error(f"Failed to load templates from DB: {e}")

    return TemplateListResponse(
        templates=templates,
        total_count=len(templates)
    )


@router.get("/templates/{template_id}", response_model=TemplateResponse)
async def get_template(template_id: str) -> TemplateResponse:
    """
    Ruft eine einzelne Vorlage ab.
    """
    init_db_if_needed()

    # System-Template pruefen
    for t in SYSTEM_TEMPLATES:
        if t["template_id"] == template_id:
            template = LessonTemplate(
                template_id=t["template_id"],
                teacher_id="system",
                name=t["name"],
                description=t.get("description", ""),
                phase_durations=t["phase_durations"],
                is_public=True,
            )
            return _build_template_response(template, is_system=True)

    # DB-Template pruefen
    if DB_ENABLED:
        try:
            from classroom_engine.repository import TemplateRepository
            db = SessionLocal()
            repo = TemplateRepository(db)
            db_template = repo.get_by_id(template_id)
            if db_template:
                template = repo.to_dataclass(db_template)
                db.close()
                return _build_template_response(template)
            db.close()
        except Exception as e:
            logger.error(f"Failed to get template {template_id}: {e}")

    raise HTTPException(status_code=404, detail="Vorlage nicht gefunden")


@router.post("/templates", response_model=TemplateResponse, status_code=201)
async def create_template(
    request: TemplateCreate,
    teacher_id: str = Query(..., description="ID des erstellenden Lehrers")
) -> TemplateResponse:
    """
    Erstellt eine neue Stunden-Vorlage.
    """
    init_db_if_needed()

    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Datenbank nicht verfuegbar - Vorlagen koennen nicht gespeichert werden"
        )

    phase_durations = request.phase_durations or get_default_durations()

    template = LessonTemplate(
        template_id=str(uuid4()),
        teacher_id=teacher_id,
        name=request.name,
        description=request.description,
        subject=request.subject,
        grade_level=request.grade_level,
        phase_durations=phase_durations,
        default_topic=request.default_topic,
        default_notes=request.default_notes,
        is_public=request.is_public,
        created_at=datetime.utcnow(),
    )

    try:
        from classroom_engine.repository import TemplateRepository
        db = SessionLocal()
        repo = TemplateRepository(db)
        db_template = repo.create(template)
        template = repo.to_dataclass(db_template)
        db.close()
        return _build_template_response(template)
    except Exception as e:
        logger.error(f"Failed to create template: {e}")
        raise HTTPException(status_code=500, detail="Fehler beim Erstellen der Vorlage")


@router.put("/templates/{template_id}", response_model=TemplateResponse)
async def update_template(
    template_id: str,
    request: TemplateUpdate,
    teacher_id: str = Query(..., description="ID des Lehrers (zur Berechtigung)")
) -> TemplateResponse:
    """
    Aktualisiert eine Stunden-Vorlage.

    Nur der Ersteller kann die Vorlage bearbeiten.
    """
    init_db_if_needed()

    # System-Templates koennen nicht bearbeitet werden
    for t in SYSTEM_TEMPLATES:
        if t["template_id"] == template_id:
            raise HTTPException(status_code=403, detail="System-Vorlagen koennen nicht bearbeitet werden")

    if not DB_ENABLED:
        raise HTTPException(status_code=503, detail="Datenbank nicht verfuegbar")

    try:
        from classroom_engine.repository import TemplateRepository
        db = SessionLocal()
        repo = TemplateRepository(db)

        db_template = repo.get_by_id(template_id)
        if not db_template:
            db.close()
            raise HTTPException(status_code=404, detail="Vorlage nicht gefunden")

        if db_template.teacher_id != teacher_id:
            db.close()
            raise HTTPException(status_code=403, detail="Keine Berechtigung")

        # Nur uebergebene Felder aktualisieren
        template = repo.to_dataclass(db_template)
        if request.name is not None:
            template.name = request.name
        if request.description is not None:
            template.description = request.description
        if request.subject is not None:
            template.subject = request.subject
        if request.grade_level is not None:
            template.grade_level = request.grade_level
        if request.phase_durations is not None:
            template.phase_durations = request.phase_durations
        if request.default_topic is not None:
            template.default_topic = request.default_topic
        if request.default_notes is not None:
            template.default_notes = request.default_notes
        if request.is_public is not None:
            template.is_public = request.is_public

        db_template = repo.update(template)
        template = repo.to_dataclass(db_template)
        db.close()
        return _build_template_response(template)

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to update template {template_id}: {e}")
        raise HTTPException(status_code=500, detail="Fehler beim Aktualisieren der Vorlage")


@router.delete("/templates/{template_id}")
async def delete_template(
    template_id: str,
    teacher_id: str = Query(..., description="ID des Lehrers (zur Berechtigung)")
) -> Dict[str, str]:
    """
    Loescht eine Stunden-Vorlage.
    """
    init_db_if_needed()

    # System-Templates koennen nicht geloescht werden
    for t in SYSTEM_TEMPLATES:
        if t["template_id"] == template_id:
            raise HTTPException(status_code=403, detail="System-Vorlagen koennen nicht geloescht werden")

    if not DB_ENABLED:
        raise HTTPException(status_code=503, detail="Datenbank nicht verfuegbar")

    try:
        from classroom_engine.repository import TemplateRepository
        db = SessionLocal()
        repo = TemplateRepository(db)

        db_template = repo.get_by_id(template_id)
        if not db_template:
            db.close()
            raise HTTPException(status_code=404, detail="Vorlage nicht gefunden")

        if db_template.teacher_id != teacher_id:
            db.close()
            raise HTTPException(status_code=403, detail="Keine Berechtigung")

        repo.delete(template_id)
        db.close()
        return {"status": "deleted", "template_id": template_id}

    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to delete template {template_id}: {e}")
        raise HTTPException(status_code=500, detail="Fehler beim Loeschen der Vorlage")


@router.post("/sessions/from-template", response_model=SessionResponse)
async def create_session_from_template(
    template_id: str = Query(..., description="ID der Vorlage"),
    teacher_id: str = Query(..., description="ID des Lehrers"),
    class_id: str = Query(..., description="ID der Klasse"),
    topic: Optional[str] = Query(None, description="Optionales Thema (ueberschreibt Default)")
) -> SessionResponse:
    """
    Erstellt eine neue Session basierend auf einer Vorlage.

    Erhoeht automatisch den Usage-Counter der Vorlage.
    """
    init_db_if_needed()

    # Template laden
    template_data = None
    is_system = False

    # System-Template pruefen
    for t in SYSTEM_TEMPLATES:
        if t["template_id"] == template_id:
            template_data = t
            is_system = True
            break

    # DB-Template pruefen
    if not template_data and DB_ENABLED:
        try:
            from classroom_engine.repository import TemplateRepository
            db = SessionLocal()
            repo = TemplateRepository(db)
            db_template = repo.get_by_id(template_id)
            if db_template:
                template_data = {
                    "phase_durations": db_template.phase_durations or get_default_durations(),
                    "subject": db_template.subject or "",
                    "default_topic": db_template.default_topic or "",
                    "default_notes": db_template.default_notes or "",
                }
                # Usage Counter erhoehen
                repo.increment_usage(template_id)
            db.close()
        except Exception as e:
            logger.error(f"Failed to load template {template_id}: {e}")

    if not template_data:
        raise HTTPException(status_code=404, detail="Vorlage nicht gefunden")

    # Session erstellen
    session = LessonSession(
        session_id=str(uuid4()),
        teacher_id=teacher_id,
        class_id=class_id,
        subject=template_data.get("subject", ""),
        topic=topic or template_data.get("default_topic", ""),
        phase_durations=template_data["phase_durations"],
        notes=template_data.get("default_notes", ""),
    )

    sessions[session.session_id] = session
    persist_session(session)

    return build_session_response(session)
