"""
State Engine API - REST API für Begleiter-Modus.

Endpoints:
- GET /api/state/context - TeacherContext abrufen
- GET /api/state/suggestions - Vorschläge abrufen
- GET /api/state/dashboard - Dashboard-Daten
- POST /api/state/milestone - Meilenstein abschließen
- POST /api/state/transition - Phasen-Übergang
"""

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

from fastapi import APIRouter, HTTPException, Query

from state_engine import (
    AnticipationEngine,
    PhaseService,
    SchoolYearPhase,
    ClassSummary,
    Event,
    get_phase_info,
)
from .state_engine_models import (
    MilestoneRequest,
    TransitionRequest,
    ContextResponse,
    SuggestionsResponse,
    DashboardResponse,
    _teacher_contexts,
    _milestones,
    get_or_create_context,
    update_context_from_services,
    get_phase_display_name,
)

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/state",
    tags=["state-engine"],
)

# Singleton instances
_engine = AnticipationEngine()
_phase_service = PhaseService()


# ============================================================================
# API Endpoints
# ============================================================================

@router.get("/context", response_model=ContextResponse)
async def get_teacher_context(teacher_id: str = Query("demo-teacher")):
    """Gibt den aggregierten TeacherContext zurück."""
    ctx = get_or_create_context(teacher_id)
    ctx = update_context_from_services(ctx)

    phase_info = get_phase_info(ctx.current_phase)

    return ContextResponse(
        context=ctx.to_dict(),
        phase_info={
            "phase": phase_info.phase.value,
            "display_name": phase_info.display_name,
            "description": phase_info.description,
            "typical_months": phase_info.typical_months,
            "required_actions": phase_info.required_actions,
            "optional_actions": phase_info.optional_actions,
        }
    )


@router.get("/phase")
async def get_current_phase(teacher_id: str = Query("demo-teacher")):
    """Gibt die aktuelle Phase mit Details zurück."""
    ctx = get_or_create_context(teacher_id)
    phase_info = get_phase_info(ctx.current_phase)

    return {
        "current_phase": ctx.current_phase.value,
        "phase_info": {
            "display_name": phase_info.display_name,
            "description": phase_info.description,
            "expected_duration_weeks": phase_info.expected_duration_weeks,
        },
        "days_in_phase": ctx.days_in_phase,
        "progress": _phase_service.get_progress_percentage(ctx),
    }


@router.get("/phases")
async def get_all_phases():
    """Gibt alle Phasen mit Metadaten zurück."""
    return {
        "phases": _phase_service.get_all_phases()
    }


@router.get("/suggestions", response_model=SuggestionsResponse)
async def get_suggestions(teacher_id: str = Query("demo-teacher")):
    """Gibt Vorschläge basierend auf dem aktuellen Kontext zurück."""
    ctx = get_or_create_context(teacher_id)
    ctx = update_context_from_services(ctx)

    suggestions = _engine.get_suggestions(ctx)
    priority_counts = _engine.count_by_priority(ctx)

    return SuggestionsResponse(
        suggestions=[s.to_dict() for s in suggestions],
        current_phase=ctx.current_phase.value,
        phase_display_name=get_phase_display_name(ctx.current_phase.value),
        priority_counts=priority_counts,
    )


@router.get("/suggestions/top")
async def get_top_suggestion(teacher_id: str = Query("demo-teacher")):
    """Gibt den wichtigsten einzelnen Vorschlag zurück."""
    ctx = get_or_create_context(teacher_id)
    ctx = update_context_from_services(ctx)

    suggestion = _engine.get_top_suggestion(ctx)

    if not suggestion:
        return {
            "suggestion": None,
            "message": "Alles erledigt! Keine offenen Aufgaben."
        }

    return {
        "suggestion": suggestion.to_dict()
    }


@router.get("/dashboard", response_model=DashboardResponse)
async def get_dashboard_data(teacher_id: str = Query("demo-teacher")):
    """Gibt alle Daten für das Begleiter-Dashboard zurück."""
    ctx = get_or_create_context(teacher_id)
    ctx = update_context_from_services(ctx)

    suggestions = _engine.get_suggestions(ctx)
    phase_info = get_phase_info(ctx.current_phase)

    required = set(phase_info.required_actions)
    completed = set(ctx.completed_milestones)
    completed_in_phase = len(required.intersection(completed))

    all_phases = []
    phase_order = [
        SchoolYearPhase.ONBOARDING,
        SchoolYearPhase.SCHOOL_YEAR_START,
        SchoolYearPhase.TEACHING_SETUP,
        SchoolYearPhase.PERFORMANCE_1,
        SchoolYearPhase.SEMESTER_END,
        SchoolYearPhase.TEACHING_2,
        SchoolYearPhase.PERFORMANCE_2,
        SchoolYearPhase.YEAR_END,
    ]

    current_idx = phase_order.index(ctx.current_phase) if ctx.current_phase in phase_order else 0

    for i, phase in enumerate(phase_order):
        info = get_phase_info(phase)
        all_phases.append({
            "phase": phase.value,
            "display_name": info.display_name,
            "short_name": info.display_name[:10],
            "is_current": phase == ctx.current_phase,
            "is_completed": i < current_idx,
            "is_future": i > current_idx,
        })

    return DashboardResponse(
        context={
            "current_phase": ctx.current_phase.value,
            "phase_display_name": phase_info.display_name,
            "phase_description": phase_info.description,
            "weeks_since_start": ctx.weeks_since_start,
            "days_in_phase": ctx.days_in_phase,
            "federal_state": ctx.federal_state,
            "school_type": ctx.school_type,
        },
        suggestions=[s.to_dict() for s in suggestions],
        stats={
            "learning_units_created": ctx.stats.learning_units_created,
            "exams_scheduled": ctx.stats.exams_scheduled,
            "exams_graded": ctx.stats.exams_graded,
            "grades_entered": ctx.stats.grades_entered,
            "classes_count": len(ctx.classes),
            "students_count": ctx.total_students,
        },
        upcoming_events=[
            {
                "type": e.type,
                "title": e.title,
                "date": e.date.isoformat(),
                "in_days": e.in_days,
                "priority": e.priority,
            }
            for e in ctx.upcoming_events[:5]
        ],
        progress={
            "completed": completed_in_phase,
            "total": len(required),
            "percentage": (completed_in_phase / len(required) * 100) if required else 100,
            "milestones_completed": list(completed.intersection(required)),
            "milestones_pending": list(required - completed),
        },
        phases=all_phases,
    )


@router.post("/milestone")
async def complete_milestone(
    request: MilestoneRequest,
    teacher_id: str = Query("demo-teacher")
):
    """Markiert einen Meilenstein als erledigt."""
    milestone = request.milestone

    if teacher_id not in _milestones:
        _milestones[teacher_id] = []

    if milestone not in _milestones[teacher_id]:
        _milestones[teacher_id].append(milestone)
        logger.info(f"Milestone '{milestone}' completed for teacher {teacher_id}")

    ctx = get_or_create_context(teacher_id)
    ctx.completed_milestones = _milestones[teacher_id]
    _teacher_contexts[teacher_id] = ctx

    new_phase = _phase_service.check_and_transition(ctx)

    if new_phase:
        ctx.current_phase = new_phase
        ctx.phase_entered_at = datetime.now()
        ctx.days_in_phase = 0
        _teacher_contexts[teacher_id] = ctx
        logger.info(f"Auto-transitioned to {new_phase} for teacher {teacher_id}")

    return {
        "success": True,
        "milestone": milestone,
        "new_phase": new_phase.value if new_phase else None,
        "current_phase": ctx.current_phase.value,
        "completed_milestones": ctx.completed_milestones,
    }


@router.post("/transition")
async def transition_phase(
    request: TransitionRequest,
    teacher_id: str = Query("demo-teacher")
):
    """Führt einen manuellen Phasen-Übergang durch."""
    try:
        target_phase = SchoolYearPhase(request.target_phase)
    except ValueError:
        raise HTTPException(
            status_code=400,
            detail=f"Ungültige Phase: {request.target_phase}"
        )

    ctx = get_or_create_context(teacher_id)

    if not _phase_service.can_transition_to(ctx, target_phase):
        raise HTTPException(
            status_code=400,
            detail=f"Übergang von {ctx.current_phase.value} zu {target_phase.value} nicht erlaubt"
        )

    old_phase = ctx.current_phase
    ctx.current_phase = target_phase
    ctx.phase_entered_at = datetime.now()
    ctx.days_in_phase = 0
    _teacher_contexts[teacher_id] = ctx

    logger.info(f"Manual transition from {old_phase} to {target_phase} for teacher {teacher_id}")

    return {
        "success": True,
        "old_phase": old_phase.value,
        "new_phase": target_phase.value,
        "phase_info": get_phase_info(target_phase).__dict__,
    }


@router.get("/next-phase")
async def get_next_phase(teacher_id: str = Query("demo-teacher")):
    """Gibt die nächste Phase und Anforderungen zurück."""
    ctx = get_or_create_context(teacher_id)
    next_phase = _phase_service.get_next_phase(ctx.current_phase)

    if not next_phase:
        return {
            "next_phase": None,
            "message": "Letzte Phase erreicht"
        }

    can_transition = _phase_service.can_transition_to(ctx, next_phase)
    next_info = get_phase_info(next_phase)
    current_info = get_phase_info(ctx.current_phase)

    missing = [
        m for m in current_info.required_actions
        if m not in ctx.completed_milestones
    ]

    return {
        "current_phase": ctx.current_phase.value,
        "next_phase": next_phase.value,
        "next_phase_info": {
            "display_name": next_info.display_name,
            "description": next_info.description,
        },
        "can_transition": can_transition,
        "missing_requirements": missing,
    }


# ============================================================================
# Demo Data Endpoints (nur für Entwicklung)
# ============================================================================

@router.post("/demo/add-class")
async def demo_add_class(
    name: str = Query(...),
    grade_level: int = Query(...),
    student_count: int = Query(25),
    teacher_id: str = Query("demo-teacher")
):
    """Demo: Fügt eine Klasse zum Kontext hinzu."""
    ctx = get_or_create_context(teacher_id)

    ctx.classes.append(ClassSummary(
        class_id=str(uuid.uuid4()),
        name=name,
        grade_level=grade_level,
        student_count=student_count,
        subject="Deutsch"
    ))
    ctx.total_students += student_count
    _teacher_contexts[teacher_id] = ctx

    return {"success": True, "classes": len(ctx.classes)}


@router.post("/demo/add-event")
async def demo_add_event(
    event_type: str = Query(...),
    title: str = Query(...),
    in_days: int = Query(...),
    teacher_id: str = Query("demo-teacher")
):
    """Demo: Fügt ein Event zum Kontext hinzu."""
    ctx = get_or_create_context(teacher_id)

    ctx.upcoming_events.append(Event(
        type=event_type,
        title=title,
        date=datetime.now() + timedelta(days=in_days),
        in_days=in_days,
        priority="high" if in_days <= 3 else "medium"
    ))
    _teacher_contexts[teacher_id] = ctx

    return {"success": True, "events": len(ctx.upcoming_events)}


@router.post("/demo/update-stats")
async def demo_update_stats(
    learning_units: int = Query(0),
    exams_scheduled: int = Query(0),
    exams_graded: int = Query(0),
    grades_entered: int = Query(0),
    unanswered_messages: int = Query(0),
    teacher_id: str = Query("demo-teacher")
):
    """Demo: Aktualisiert Statistiken."""
    ctx = get_or_create_context(teacher_id)

    if learning_units:
        ctx.stats.learning_units_created = learning_units
    if exams_scheduled:
        ctx.stats.exams_scheduled = exams_scheduled
    if exams_graded:
        ctx.stats.exams_graded = exams_graded
    if grades_entered:
        ctx.stats.grades_entered = grades_entered
    if unanswered_messages:
        ctx.stats.unanswered_messages = unanswered_messages

    _teacher_contexts[teacher_id] = ctx

    return {"success": True, "stats": ctx.stats.__dict__}


@router.post("/demo/reset")
async def demo_reset(teacher_id: str = Query("demo-teacher")):
    """Demo: Setzt den Kontext zurück."""
    if teacher_id in _teacher_contexts:
        del _teacher_contexts[teacher_id]
    if teacher_id in _milestones:
        del _milestones[teacher_id]

    return {"success": True, "message": "Kontext zurückgesetzt"}
