"""
Classroom API - Context Core Routes

Teacher context, onboarding endpoints (Phase 8).
"""

from typing import Dict, Any
from datetime import datetime
import logging

from fastapi import APIRouter, HTTPException, Query, Depends

from classroom_engine import (
    FEDERAL_STATES,
    SCHOOL_TYPES,
    MacroPhaseEnum,
)

from ..models import (
    TeacherContextResponse,
    SchoolInfo,
    SchoolYearInfo,
    MacroPhaseInfo,
    CoreCounts,
    ContextFlags,
    UpdateContextRequest,
)
from ..services.persistence import (
    init_db_if_needed,
    DB_ENABLED,
    SessionLocal,
)

logger = logging.getLogger(__name__)

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


def get_db():
    """Database session dependency."""
    if DB_ENABLED and SessionLocal:
        db = SessionLocal()
        try:
            yield db
        finally:
            db.close()
    else:
        yield None


def _get_macro_phase_label(phase) -> str:
    """Gibt den Anzeigenamen einer Makro-Phase zurueck."""
    labels = {
        "onboarding": "Einrichtung",
        "schuljahresstart": "Schuljahresstart",
        "unterrichtsaufbau": "Unterrichtsaufbau",
        "leistungsphase_1": "Leistungsphase 1",
        "halbjahresabschluss": "Halbjahresabschluss",
        "leistungsphase_2": "Leistungsphase 2",
        "jahresabschluss": "Jahresabschluss",
    }
    phase_value = phase.value if hasattr(phase, 'value') else str(phase)
    return labels.get(phase_value, phase_value)


# === Context Endpoints ===

@router.get("/v1/context", response_model=TeacherContextResponse)
async def get_teacher_context(
    teacher_id: str = Query(..., description="Teacher ID"),
    db=Depends(get_db)
):
    """
    Liefert den aktuellen Makro-Kontext eines Lehrers.

    Der Kontext beinhaltet:
    - Schul-Informationen (Bundesland, Schulart)
    - Schuljahr-Daten (aktuelles Jahr, Woche)
    - Makro-Phase (ONBOARDING bis JAHRESABSCHLUSS)
    - Zaehler (Klassen, geplante Klausuren, etc.)
    - Status-Flags (Onboarding abgeschlossen, etc.)
    """
    if DB_ENABLED and db:
        try:
            from classroom_engine.repository import TeacherContextRepository, SchoolyearEventRepository
            repo = TeacherContextRepository(db)
            context = repo.get_or_create(teacher_id)

            # Zaehler berechnen
            event_repo = SchoolyearEventRepository(db)
            upcoming_exams = event_repo.get_upcoming(teacher_id, days=30)
            exams_count = len([e for e in upcoming_exams if e.event_type.value == "exam"])

            return TeacherContextResponse(
                schema_version="1.0",
                teacher_id=teacher_id,
                school=SchoolInfo(
                    federal_state=context.federal_state or "BY",
                    federal_state_name=FEDERAL_STATES.get(context.federal_state, ""),
                    school_type=context.school_type or "gymnasium",
                    school_type_name=SCHOOL_TYPES.get(context.school_type, ""),
                ),
                school_year=SchoolYearInfo(
                    id=context.schoolyear or "2024-2025",
                    start=context.schoolyear_start.isoformat() if context.schoolyear_start else None,
                    current_week=context.current_week or 1,
                ),
                macro_phase=MacroPhaseInfo(
                    id=context.macro_phase.value,
                    label=_get_macro_phase_label(context.macro_phase),
                    confidence=1.0,
                ),
                core_counts=CoreCounts(
                    classes=1 if context.has_classes else 0,
                    exams_scheduled=exams_count,
                    corrections_pending=0,
                ),
                flags=ContextFlags(
                    onboarding_completed=context.onboarding_completed,
                    has_classes=context.has_classes,
                    has_schedule=context.has_schedule,
                    is_exam_period=context.is_exam_period,
                    is_before_holidays=context.is_before_holidays,
                ),
            )
        except Exception as e:
            logger.error(f"Failed to get teacher context: {e}")
            raise HTTPException(status_code=500, detail=f"Fehler beim Laden des Kontexts: {e}")

    # Fallback ohne DB
    return TeacherContextResponse(
        schema_version="1.0",
        teacher_id=teacher_id,
        school=SchoolInfo(
            federal_state="BY",
            federal_state_name="Bayern",
            school_type="gymnasium",
            school_type_name="Gymnasium",
        ),
        school_year=SchoolYearInfo(
            id="2024-2025",
            start=None,
            current_week=1,
        ),
        macro_phase=MacroPhaseInfo(
            id="onboarding",
            label="Einrichtung",
            confidence=1.0,
        ),
        core_counts=CoreCounts(),
        flags=ContextFlags(),
    )


@router.put("/v1/context", response_model=TeacherContextResponse)
async def update_teacher_context(
    teacher_id: str,
    request: UpdateContextRequest,
    db=Depends(get_db)
):
    """
    Aktualisiert den Kontext eines Lehrers.
    """
    if not DB_ENABLED or not db:
        raise HTTPException(status_code=503, detail="Datenbank nicht verfuegbar")

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

        # Validierung
        if request.federal_state and request.federal_state not in FEDERAL_STATES:
            raise HTTPException(status_code=400, detail=f"Ungueltiges Bundesland: {request.federal_state}")
        if request.school_type and request.school_type not in SCHOOL_TYPES:
            raise HTTPException(status_code=400, detail=f"Ungueltige Schulart: {request.school_type}")

        # Parse datetime if provided
        schoolyear_start = None
        if request.schoolyear_start:
            schoolyear_start = datetime.fromisoformat(request.schoolyear_start.replace('Z', '+00:00'))

        repo.update_context(
            teacher_id=teacher_id,
            federal_state=request.federal_state,
            school_type=request.school_type,
            schoolyear=request.schoolyear,
            schoolyear_start=schoolyear_start,
            macro_phase=request.macro_phase,
            current_week=request.current_week,
        )

        return await get_teacher_context(teacher_id, db)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Failed to update teacher context: {e}")
        raise HTTPException(status_code=500, detail=f"Fehler beim Aktualisieren: {e}")


@router.post("/v1/context/complete-onboarding")
async def complete_onboarding(
    teacher_id: str = Query(...),
    db=Depends(get_db)
):
    """Markiert das Onboarding als abgeschlossen."""
    if not DB_ENABLED or not db:
        return {"success": True, "macro_phase": "schuljahresstart", "note": "DB not available"}

    try:
        from classroom_engine.repository import TeacherContextRepository
        repo = TeacherContextRepository(db)
        context = repo.complete_onboarding(teacher_id)
        return {
            "success": True,
            "macro_phase": context.macro_phase.value,
            "teacher_id": teacher_id,
        }
    except Exception as e:
        logger.error(f"Failed to complete onboarding: {e}")
        raise HTTPException(status_code=500, detail=f"Fehler: {e}")


@router.post("/v1/context/reset-onboarding")
async def reset_onboarding(
    teacher_id: str = Query(...),
    db=Depends(get_db)
):
    """Setzt das Onboarding zurueck (fuer Tests)."""
    if not DB_ENABLED or not db:
        return {"success": True, "macro_phase": "onboarding", "note": "DB not available"}

    try:
        from classroom_engine.repository import TeacherContextRepository
        repo = TeacherContextRepository(db)
        context = repo.get_or_create(teacher_id)
        context.onboarding_completed = False
        context.macro_phase = MacroPhaseEnum.ONBOARDING
        db.commit()
        db.refresh(context)
        return {
            "success": True,
            "macro_phase": "onboarding",
            "teacher_id": teacher_id,
        }
    except Exception as e:
        logger.error(f"Failed to reset onboarding: {e}")
        raise HTTPException(status_code=500, detail=f"Fehler: {e}")
