"""
Classroom API - Analytics Routes

Analytics and reflection endpoints (Phase 5).
"""

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

from fastapi import APIRouter, HTTPException, Query

from classroom_engine import LessonReflection

from ..models import (
    SessionSummaryResponse,
    TeacherAnalyticsResponse,
    ReflectionCreate,
    ReflectionUpdate,
    ReflectionResponse,
)
from ..services.persistence import (
    init_db_if_needed,
    DB_ENABLED,
    SessionLocal,
)

logger = logging.getLogger(__name__)

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


# === Analytics Endpoints ===

@router.get("/analytics/session/{session_id}")
async def get_session_summary(session_id: str) -> SessionSummaryResponse:
    """
    Gibt die Analytics-Zusammenfassung einer Session zurueck.

    Berechnet Phasen-Dauer Statistiken, Overtime und Pausen-Analyse.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import AnalyticsRepository
        repo = AnalyticsRepository(db)
        summary = repo.get_session_summary(session_id)

        if not summary:
            raise HTTPException(
                status_code=404,
                detail=f"Session {session_id} not found"
            )

        return SessionSummaryResponse(**summary.to_dict())


@router.get("/analytics/teacher/{teacher_id}")
async def get_teacher_analytics(
    teacher_id: str,
    days: int = Query(30, ge=1, le=365)
) -> TeacherAnalyticsResponse:
    """
    Gibt aggregierte Analytics fuer einen Lehrer zurueck.

    Berechnet Trends ueber den angegebenen Zeitraum.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    period_end = datetime.utcnow()
    period_start = period_end - timedelta(days=days)

    with SessionLocal() as db:
        from classroom_engine.repository import AnalyticsRepository
        repo = AnalyticsRepository(db)
        analytics = repo.get_teacher_analytics(
            teacher_id, period_start, period_end
        )

        return TeacherAnalyticsResponse(**analytics.to_dict())


@router.get("/analytics/phase-trends/{teacher_id}/{phase}")
async def get_phase_trends(
    teacher_id: str,
    phase: str,
    limit: int = Query(20, ge=1, le=100)
) -> Dict[str, Any]:
    """
    Gibt die Dauer-Trends fuer eine Phase zurueck.

    Nuetzlich fuer Charts und Visualisierungen.
    """
    if phase not in ["einstieg", "erarbeitung", "sicherung", "transfer", "reflexion"]:
        raise HTTPException(
            status_code=400,
            detail=f"Invalid phase: {phase}"
        )

    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import AnalyticsRepository
        repo = AnalyticsRepository(db)
        trends = repo.get_phase_duration_trends(teacher_id, phase, limit)

        return {
            "teacher_id": teacher_id,
            "phase": phase,
            "data_points": trends,
            "count": len(trends)
        }


@router.get("/analytics/overtime/{teacher_id}")
async def get_overtime_analysis(
    teacher_id: str,
    limit: int = Query(30, ge=1, le=100)
) -> Dict[str, Any]:
    """
    Analysiert Overtime-Muster nach Phase.

    Zeigt welche Phasen am haeufigsten ueberzogen werden.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import AnalyticsRepository
        repo = AnalyticsRepository(db)
        analysis = repo.get_overtime_analysis(teacher_id, limit)

        return {
            "teacher_id": teacher_id,
            "sessions_analyzed": limit,
            "phases": analysis
        }


# === Reflection Endpoints ===

@router.post("/reflections", status_code=201)
async def create_reflection(data: ReflectionCreate) -> ReflectionResponse:
    """
    Erstellt eine Post-Lesson Reflection.

    Erlaubt Lehrern, nach der Stunde Notizen zu speichern.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import ReflectionRepository
        repo = ReflectionRepository(db)

        # Pruefen ob schon eine Reflection existiert
        existing = repo.get_by_session(data.session_id)
        if existing:
            raise HTTPException(
                status_code=409,
                detail=f"Reflection for session {data.session_id} already exists"
            )

        reflection = LessonReflection(
            reflection_id=str(uuid.uuid4()),
            session_id=data.session_id,
            teacher_id=data.teacher_id,
            notes=data.notes,
            overall_rating=data.overall_rating,
            what_worked=data.what_worked,
            improvements=data.improvements,
            notes_for_next_lesson=data.notes_for_next_lesson,
            created_at=datetime.utcnow(),
        )

        db_reflection = repo.create(reflection)
        result = repo.to_dataclass(db_reflection)

        return ReflectionResponse(**result.to_dict())


@router.get("/reflections/session/{session_id}")
async def get_reflection_by_session(session_id: str) -> ReflectionResponse:
    """
    Holt die Reflection einer Session.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import ReflectionRepository
        repo = ReflectionRepository(db)
        db_reflection = repo.get_by_session(session_id)

        if not db_reflection:
            raise HTTPException(
                status_code=404,
                detail=f"No reflection for session {session_id}"
            )

        result = repo.to_dataclass(db_reflection)
        return ReflectionResponse(**result.to_dict())


@router.get("/reflections/teacher/{teacher_id}")
async def get_reflections_by_teacher(
    teacher_id: str,
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0)
) -> Dict[str, Any]:
    """
    Holt alle Reflections eines Lehrers.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import ReflectionRepository
        repo = ReflectionRepository(db)
        db_reflections = repo.get_by_teacher(teacher_id, limit, offset)

        reflections = [
            repo.to_dataclass(r).to_dict()
            for r in db_reflections
        ]

        return {
            "teacher_id": teacher_id,
            "reflections": reflections,
            "count": len(reflections),
            "offset": offset,
            "limit": limit
        }


@router.put("/reflections/{reflection_id}")
async def update_reflection(
    reflection_id: str,
    data: ReflectionUpdate,
    teacher_id: str = Query(...)
) -> ReflectionResponse:
    """
    Aktualisiert eine Reflection.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import ReflectionRepository
        repo = ReflectionRepository(db)
        db_reflection = repo.get_by_id(reflection_id)

        if not db_reflection:
            raise HTTPException(
                status_code=404,
                detail=f"Reflection {reflection_id} not found"
            )

        if db_reflection.teacher_id != teacher_id:
            raise HTTPException(
                status_code=403,
                detail="Not authorized to update this reflection"
            )

        # Vorhandene Werte beibehalten wenn nicht im Update
        reflection = repo.to_dataclass(db_reflection)

        if data.notes is not None:
            reflection.notes = data.notes
        if data.overall_rating is not None:
            reflection.overall_rating = data.overall_rating
        if data.what_worked is not None:
            reflection.what_worked = data.what_worked
        if data.improvements is not None:
            reflection.improvements = data.improvements
        if data.notes_for_next_lesson is not None:
            reflection.notes_for_next_lesson = data.notes_for_next_lesson

        reflection.updated_at = datetime.utcnow()

        db_updated = repo.update(reflection)
        result = repo.to_dataclass(db_updated)

        return ReflectionResponse(**result.to_dict())


@router.delete("/reflections/{reflection_id}")
async def delete_reflection(
    reflection_id: str,
    teacher_id: str = Query(...)
) -> Dict[str, Any]:
    """
    Loescht eine Reflection.
    """
    if not DB_ENABLED:
        raise HTTPException(
            status_code=503,
            detail="Database not available"
        )

    init_db_if_needed()

    with SessionLocal() as db:
        from classroom_engine.repository import ReflectionRepository
        repo = ReflectionRepository(db)
        db_reflection = repo.get_by_id(reflection_id)

        if not db_reflection:
            raise HTTPException(
                status_code=404,
                detail=f"Reflection {reflection_id} not found"
            )

        if db_reflection.teacher_id != teacher_id:
            raise HTTPException(
                status_code=403,
                detail="Not authorized to delete this reflection"
            )

        success = repo.delete(reflection_id)

        return {
            "success": success,
            "deleted_id": reflection_id
        }
