"""
State Engine API - Pydantic Models und Helper Functions.
"""

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

from pydantic import BaseModel, Field

from state_engine import (
    SchoolYearPhase,
    ClassSummary,
    Event,
    TeacherContext,
    TeacherStats,
    get_phase_info,
)


# ============================================================================
# In-Memory Storage (später durch DB ersetzen)
# ============================================================================

_teacher_contexts: Dict[str, TeacherContext] = {}
_milestones: Dict[str, List[str]] = {}  # teacher_id -> milestones


# ============================================================================
# Pydantic Models
# ============================================================================

class MilestoneRequest(BaseModel):
    """Request zum Abschließen eines Meilensteins."""
    milestone: str = Field(..., description="Name des Meilensteins")


class TransitionRequest(BaseModel):
    """Request für Phasen-Übergang."""
    target_phase: str = Field(..., description="Zielphase")


class ContextResponse(BaseModel):
    """Response mit TeacherContext."""
    context: Dict[str, Any]
    phase_info: Dict[str, Any]


class SuggestionsResponse(BaseModel):
    """Response mit Vorschlägen."""
    suggestions: List[Dict[str, Any]]
    current_phase: str
    phase_display_name: str
    priority_counts: Dict[str, int]


class DashboardResponse(BaseModel):
    """Response mit Dashboard-Daten."""
    context: Dict[str, Any]
    suggestions: List[Dict[str, Any]]
    stats: Dict[str, Any]
    upcoming_events: List[Dict[str, Any]]
    progress: Dict[str, Any]
    phases: List[Dict[str, Any]]


# ============================================================================
# Helper Functions
# ============================================================================

def get_or_create_context(teacher_id: str) -> TeacherContext:
    """
    Holt oder erstellt TeacherContext.

    In Produktion würde dies aus der Datenbank geladen.
    """
    if teacher_id not in _teacher_contexts:
        now = datetime.now()
        school_year_start = datetime(now.year if now.month >= 8 else now.year - 1, 8, 1)
        weeks_since_start = (now - school_year_start).days // 7

        month = now.month
        if month in [8, 9]:
            phase = SchoolYearPhase.SCHOOL_YEAR_START
        elif month in [10, 11]:
            phase = SchoolYearPhase.TEACHING_SETUP
        elif month == 12:
            phase = SchoolYearPhase.PERFORMANCE_1
        elif month in [1, 2]:
            phase = SchoolYearPhase.SEMESTER_END
        elif month in [3, 4]:
            phase = SchoolYearPhase.TEACHING_2
        elif month in [5, 6]:
            phase = SchoolYearPhase.PERFORMANCE_2
        else:
            phase = SchoolYearPhase.YEAR_END

        _teacher_contexts[teacher_id] = TeacherContext(
            teacher_id=teacher_id,
            school_id=str(uuid.uuid4()),
            school_year_id=str(uuid.uuid4()),
            federal_state="niedersachsen",
            school_type="gymnasium",
            school_year_start=school_year_start,
            current_phase=phase,
            phase_entered_at=now - timedelta(days=7),
            weeks_since_start=weeks_since_start,
            days_in_phase=7,
            classes=[],
            total_students=0,
            upcoming_events=[],
            completed_milestones=_milestones.get(teacher_id, []),
            pending_milestones=[],
            stats=TeacherStats(),
        )

    return _teacher_contexts[teacher_id]


def update_context_from_services(ctx: TeacherContext) -> TeacherContext:
    """
    Aktualisiert Kontext mit Daten aus anderen Services.

    In Produktion würde dies von school-service, gradebook etc. laden.
    """
    ctx.days_in_phase = (datetime.now() - ctx.phase_entered_at).days
    ctx.completed_milestones = _milestones.get(ctx.teacher_id, [])

    phase_info = get_phase_info(ctx.current_phase)
    ctx.pending_milestones = [
        m for m in phase_info.required_actions
        if m not in ctx.completed_milestones
    ]

    return ctx


def get_phase_display_name(phase: str) -> str:
    """Gibt Display-Name für Phase zurück."""
    try:
        return get_phase_info(SchoolYearPhase(phase)).display_name
    except (ValueError, KeyError):
        return phase
