"""
Classroom API - Session Core Routes

Session CRUD, lifecycle, and history endpoints.
"""

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

from fastapi import APIRouter, HTTPException, Query

from classroom_engine import (
    LessonPhase,
    LessonSession,
    LessonStateMachine,
    PhaseTimer,
    LESSON_PHASES,
)

from ..models import (
    CreateSessionRequest,
    NotesRequest,
    PhaseInfo,
    TimerStatus,
    SessionResponse,
    PhasesListResponse,
    ActiveSessionsResponse,
    SessionHistoryItem,
    SessionHistoryResponse,
)
from ..services.persistence import (
    sessions,
    init_db_if_needed,
    persist_session,
    get_session_or_404,
    DB_ENABLED,
    SessionLocal,
)
from ..websocket_manager import notify_phase_change, notify_session_ended

logger = logging.getLogger(__name__)

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


def build_session_response(session: LessonSession) -> SessionResponse:
    """Baut die vollstaendige Session-Response."""
    fsm = LessonStateMachine()
    timer = PhaseTimer()

    timer_status = timer.get_phase_status(session)
    phases_info = fsm.get_phases_info(session)

    return SessionResponse(
        session_id=session.session_id,
        teacher_id=session.teacher_id,
        class_id=session.class_id,
        subject=session.subject,
        topic=session.topic,
        current_phase=session.current_phase.value,
        phase_display_name=session.get_phase_display_name(),
        phase_started_at=session.phase_started_at.isoformat() if session.phase_started_at else None,
        lesson_started_at=session.lesson_started_at.isoformat() if session.lesson_started_at else None,
        lesson_ended_at=session.lesson_ended_at.isoformat() if session.lesson_ended_at else None,
        timer=TimerStatus(**timer_status),
        phases=[PhaseInfo(**p) for p in phases_info],
        phase_history=session.phase_history,
        notes=session.notes,
        homework=session.homework,
        is_active=fsm.is_lesson_active(session),
        is_ended=fsm.is_lesson_ended(session),
        is_paused=session.is_paused,
    )


# === Session CRUD Endpoints ===

@router.post("/sessions", response_model=SessionResponse)
async def create_session(request: CreateSessionRequest) -> SessionResponse:
    """Erstellt eine neue Unterrichtsstunde (Session)."""
    init_db_if_needed()

    phase_durations = {
        "einstieg": 8, "erarbeitung": 20, "sicherung": 10,
        "transfer": 7, "reflexion": 5,
    }
    if request.phase_durations:
        phase_durations.update(request.phase_durations)

    session = LessonSession(
        session_id=str(uuid4()),
        teacher_id=request.teacher_id,
        class_id=request.class_id,
        subject=request.subject,
        topic=request.topic,
        phase_durations=phase_durations,
    )

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


@router.get("/sessions/{session_id}", response_model=SessionResponse)
async def get_session(session_id: str) -> SessionResponse:
    """Ruft den aktuellen Status einer Session ab."""
    session = get_session_or_404(session_id)
    return build_session_response(session)


@router.post("/sessions/{session_id}/start", response_model=SessionResponse)
async def start_lesson(session_id: str) -> SessionResponse:
    """Startet die Unterrichtsstunde."""
    session = get_session_or_404(session_id)

    if session.current_phase != LessonPhase.NOT_STARTED:
        raise HTTPException(
            status_code=400,
            detail=f"Stunde bereits gestartet (aktuelle Phase: {session.current_phase.value})"
        )

    fsm = LessonStateMachine()
    session = fsm.transition(session, LessonPhase.EINSTIEG)
    persist_session(session)
    return build_session_response(session)


@router.post("/sessions/{session_id}/next-phase", response_model=SessionResponse)
async def next_phase(session_id: str) -> SessionResponse:
    """Wechselt zur naechsten Phase."""
    session = get_session_or_404(session_id)

    fsm = LessonStateMachine()
    next_p = fsm.next_phase(session.current_phase)

    if not next_p:
        raise HTTPException(
            status_code=400,
            detail=f"Keine naechste Phase verfuegbar (aktuelle Phase: {session.current_phase.value})"
        )

    session = fsm.transition(session, next_p)
    persist_session(session)

    response = build_session_response(session)
    await notify_phase_change(session_id, session.current_phase.value, {
        "phase_display_name": session.get_phase_display_name(),
        "is_ended": session.current_phase == LessonPhase.ENDED
    })
    return response


@router.post("/sessions/{session_id}/end", response_model=SessionResponse)
async def end_lesson(session_id: str) -> SessionResponse:
    """Beendet die Unterrichtsstunde sofort."""
    session = get_session_or_404(session_id)

    if session.current_phase == LessonPhase.ENDED:
        raise HTTPException(status_code=400, detail="Stunde bereits beendet")
    if session.current_phase == LessonPhase.NOT_STARTED:
        raise HTTPException(status_code=400, detail="Stunde noch nicht gestartet")

    fsm = LessonStateMachine()
    while session.current_phase != LessonPhase.ENDED:
        next_p = fsm.next_phase(session.current_phase)
        if next_p:
            session = fsm.transition(session, next_p)
        else:
            break

    persist_session(session)
    await notify_session_ended(session_id)
    return build_session_response(session)


@router.put("/sessions/{session_id}/notes", response_model=SessionResponse)
async def update_notes(session_id: str, request: NotesRequest) -> SessionResponse:
    """Aktualisiert Notizen und Hausaufgaben der Stunde."""
    session = get_session_or_404(session_id)
    session.notes = request.notes
    session.homework = request.homework
    persist_session(session)
    return build_session_response(session)


@router.delete("/sessions/{session_id}")
async def delete_session(session_id: str) -> Dict[str, str]:
    """Loescht eine Session."""
    if session_id not in sessions:
        raise HTTPException(status_code=404, detail="Session nicht gefunden")

    del sessions[session_id]

    if DB_ENABLED:
        try:
            from ..services.persistence import delete_session_from_db
            delete_session_from_db(session_id)
        except Exception as e:
            logger.error(f"Failed to delete session {session_id} from DB: {e}")

    return {"status": "deleted", "session_id": session_id}


# === Session History (Feature f17) ===

@router.get("/history/{teacher_id}", response_model=SessionHistoryResponse)
async def get_session_history(
    teacher_id: str,
    limit: int = Query(20, ge=1, le=100),
    offset: int = Query(0, ge=0)
) -> SessionHistoryResponse:
    """Ruft die Session-History eines Lehrers ab (Feature f17)."""
    init_db_if_needed()

    if not DB_ENABLED:
        ended_sessions = [
            s for s in sessions.values()
            if s.teacher_id == teacher_id and s.current_phase == LessonPhase.ENDED
        ]
        ended_sessions.sort(key=lambda x: x.lesson_ended_at or datetime.min, reverse=True)
        paginated = ended_sessions[offset:offset + limit]

        items = []
        for s in paginated:
            duration = None
            if s.lesson_started_at and s.lesson_ended_at:
                duration = int((s.lesson_ended_at - s.lesson_started_at).total_seconds() / 60)

            items.append(SessionHistoryItem(
                session_id=s.session_id, teacher_id=s.teacher_id,
                class_id=s.class_id, subject=s.subject, topic=s.topic,
                lesson_started_at=s.lesson_started_at.isoformat() if s.lesson_started_at else None,
                lesson_ended_at=s.lesson_ended_at.isoformat() if s.lesson_ended_at else None,
                total_duration_minutes=duration,
                phases_completed=len(s.phase_history),
                notes=s.notes, homework=s.homework,
            ))

        return SessionHistoryResponse(
            sessions=items, total_count=len(ended_sessions), limit=limit, offset=offset,
        )

    try:
        from classroom_engine.repository import SessionRepository
        db = SessionLocal()
        repo = SessionRepository(db)
        db_sessions = repo.get_history_by_teacher(teacher_id, limit, offset)

        from classroom_engine.db_models import LessonSessionDB, LessonPhaseEnum
        total_count = db.query(LessonSessionDB).filter(
            LessonSessionDB.teacher_id == teacher_id,
            LessonSessionDB.current_phase == LessonPhaseEnum.ENDED
        ).count()

        items = []
        for db_session in db_sessions:
            duration = None
            if db_session.lesson_started_at and db_session.lesson_ended_at:
                duration = int((db_session.lesson_ended_at - db_session.lesson_started_at).total_seconds() / 60)

            phase_history = db_session.phase_history or []

            items.append(SessionHistoryItem(
                session_id=db_session.id, teacher_id=db_session.teacher_id,
                class_id=db_session.class_id, subject=db_session.subject, topic=db_session.topic,
                lesson_started_at=db_session.lesson_started_at.isoformat() if db_session.lesson_started_at else None,
                lesson_ended_at=db_session.lesson_ended_at.isoformat() if db_session.lesson_ended_at else None,
                total_duration_minutes=duration,
                phases_completed=len(phase_history),
                notes=db_session.notes or "", homework=db_session.homework or "",
            ))

        db.close()

        return SessionHistoryResponse(
            sessions=items, total_count=total_count, limit=limit, offset=offset,
        )

    except Exception as e:
        logger.error(f"Failed to get session history: {e}")
        raise HTTPException(status_code=500, detail="Fehler beim Laden der History")
