"""
Datenmodelle fuer die Classroom State Machine.
"""

from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional, List, Dict, Any
from enum import Enum


class LessonPhase(str, Enum):
    """Unterrichtsphasen als Enum."""
    NOT_STARTED = "not_started"
    EINSTIEG = "einstieg"
    ERARBEITUNG = "erarbeitung"
    SICHERUNG = "sicherung"
    TRANSFER = "transfer"
    REFLEXION = "reflexion"
    ENDED = "ended"


@dataclass
class PhaseConfig:
    """Konfiguration einer einzelnen Phase."""
    phase: LessonPhase
    display_name: str
    duration_minutes: int
    activities: List[str]
    icon: str
    description: str = ""


# Phasen-Definitionen mit Default-Werten
LESSON_PHASES: Dict[str, Dict[str, Any]] = {
    "einstieg": {
        "display_name": "Einstieg",
        "default_duration_minutes": 8,
        "next_phase": "erarbeitung",
        "activities": ["warmup", "motivation", "problem_introduction"],
        "icon": "play_circle",
        "description": "Motivation und Problemstellung"
    },
    "erarbeitung": {
        "display_name": "Erarbeitung",
        "default_duration_minutes": 20,
        "next_phase": "sicherung",
        "activities": ["instruction", "individual_work", "partner_work", "group_work"],
        "icon": "edit",
        "description": "Hauptarbeitsphase mit Input und Uebungen"
    },
    "sicherung": {
        "display_name": "Sicherung",
        "default_duration_minutes": 10,
        "next_phase": "transfer",
        "activities": ["summary", "visualization", "documentation"],
        "icon": "save",
        "description": "Ergebnisse festhalten und zusammenfassen"
    },
    "transfer": {
        "display_name": "Transfer",
        "default_duration_minutes": 7,
        "next_phase": "reflexion",
        "activities": ["application", "real_world_connection", "differentiation"],
        "icon": "compare_arrows",
        "description": "Anwendung auf neue Kontexte"
    },
    "reflexion": {
        "display_name": "Reflexion",
        "default_duration_minutes": 5,
        "next_phase": None,
        "activities": ["feedback", "homework", "preview"],
        "icon": "lightbulb",
        "description": "Rueckblick, Hausaufgaben und Ausblick"
    }
}


def get_default_durations() -> Dict[str, int]:
    """Gibt die Standard-Phasendauern zurueck."""
    return {
        phase_id: config["default_duration_minutes"]
        for phase_id, config in LESSON_PHASES.items()
    }


@dataclass
class LessonSession:
    """Repräsentiert eine laufende Unterrichtsstunde."""
    session_id: str
    teacher_id: str
    class_id: str
    subject: str
    topic: Optional[str] = None

    # State
    current_phase: LessonPhase = LessonPhase.NOT_STARTED
    phase_started_at: Optional[datetime] = None
    lesson_started_at: Optional[datetime] = None
    lesson_ended_at: Optional[datetime] = None

    # Pause state (Feature f26/f27)
    is_paused: bool = False
    pause_started_at: Optional[datetime] = None
    total_paused_seconds: int = 0  # Cumulative pause time for current phase

    # Phase durations (customizable per session)
    phase_durations: Dict[str, int] = field(default_factory=get_default_durations)

    # History
    phase_history: List[Dict[str, Any]] = field(default_factory=list)

    # Metadata
    notes: str = ""
    homework: str = ""

    def to_dict(self) -> Dict[str, Any]:
        """Konvertiert die Session in ein Dictionary."""
        return {
            "session_id": self.session_id,
            "teacher_id": self.teacher_id,
            "class_id": self.class_id,
            "subject": self.subject,
            "topic": self.topic,
            "current_phase": self.current_phase.value,
            "phase_started_at": self.phase_started_at.isoformat() if self.phase_started_at else None,
            "lesson_started_at": self.lesson_started_at.isoformat() if self.lesson_started_at else None,
            "lesson_ended_at": self.lesson_ended_at.isoformat() if self.lesson_ended_at else None,
            "is_paused": self.is_paused,
            "pause_started_at": self.pause_started_at.isoformat() if self.pause_started_at else None,
            "total_paused_seconds": self.total_paused_seconds,
            "phase_durations": self.phase_durations,
            "phase_history": self.phase_history,
            "notes": self.notes,
            "homework": self.homework,
        }

    def get_phase_display_name(self) -> str:
        """Gibt den Anzeigenamen der aktuellen Phase zurueck."""
        if self.current_phase == LessonPhase.NOT_STARTED:
            return "Nicht gestartet"
        elif self.current_phase == LessonPhase.ENDED:
            return "Beendet"
        else:
            return LESSON_PHASES.get(self.current_phase.value, {}).get("display_name", "Unbekannt")

    def get_total_duration_minutes(self) -> int:
        """Gibt die Gesamtdauer aller Phasen in Minuten zurueck."""
        return sum(self.phase_durations.values())


@dataclass
class LessonTemplate:
    """
    Vorlage fuer Unterrichtsstunden (Feature f37).

    Ermoeglicht Lehrern, haeufig genutzte Stundenkonfigurationen zu speichern.
    """
    template_id: str
    teacher_id: str  # Ersteller der Vorlage
    name: str
    description: str = ""
    subject: str = ""
    grade_level: str = ""  # z.B. "7", "10", "Oberstufe"

    # Phasenkonfiguration
    phase_durations: Dict[str, int] = field(default_factory=get_default_durations)

    # Optionale Vorbelegungen
    default_topic: str = ""
    default_notes: str = ""

    # Metadaten
    is_public: bool = False  # Oeffentlich fuer alle Lehrer?
    usage_count: int = 0
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    def to_dict(self) -> Dict[str, Any]:
        """Konvertiert das Template in ein Dictionary."""
        return {
            "template_id": self.template_id,
            "teacher_id": self.teacher_id,
            "name": self.name,
            "description": self.description,
            "subject": self.subject,
            "grade_level": self.grade_level,
            "phase_durations": self.phase_durations,
            "default_topic": self.default_topic,
            "default_notes": self.default_notes,
            "is_public": self.is_public,
            "usage_count": self.usage_count,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "total_duration_minutes": sum(self.phase_durations.values()),
        }


# Vordefinierte System-Templates
SYSTEM_TEMPLATES: List[Dict[str, Any]] = [
    {
        "template_id": "system_standard_45",
        "name": "Standard 45 Min",
        "description": "Klassische Unterrichtsstunde mit 45 Minuten",
        "phase_durations": {
            "einstieg": 5,
            "erarbeitung": 20,
            "sicherung": 10,
            "transfer": 5,
            "reflexion": 5,
        },
        "is_public": True,
    },
    {
        "template_id": "system_standard_90",
        "name": "Doppelstunde 90 Min",
        "description": "Ausfuehrliche Doppelstunde mit mehr Zeit fuer Erarbeitung",
        "phase_durations": {
            "einstieg": 10,
            "erarbeitung": 40,
            "sicherung": 20,
            "transfer": 10,
            "reflexion": 10,
        },
        "is_public": True,
    },
    {
        "template_id": "system_workshop",
        "name": "Workshop-Stil",
        "description": "Praxisorientiert mit langer Erarbeitungsphase",
        "phase_durations": {
            "einstieg": 5,
            "erarbeitung": 30,
            "sicherung": 5,
            "transfer": 5,
            "reflexion": 5,
        },
        "is_public": True,
    },
    {
        "template_id": "system_discussion",
        "name": "Diskussion & Reflexion",
        "description": "Fuer Themen mit viel Diskussionsbedarf",
        "phase_durations": {
            "einstieg": 8,
            "erarbeitung": 15,
            "sicherung": 7,
            "transfer": 10,
            "reflexion": 10,
        },
        "is_public": True,
    },
    {
        "template_id": "system_test_prep",
        "name": "Pruefungsvorbereitung",
        "description": "Kompakte Wiederholung vor Tests",
        "phase_durations": {
            "einstieg": 3,
            "erarbeitung": 25,
            "sicherung": 12,
            "transfer": 3,
            "reflexion": 2,
        },
        "is_public": True,
    },
]


@dataclass
class PhaseSuggestion:
    """Ein Vorschlag fuer eine Aktivitaet in einer Phase (Feature f18)."""
    id: str
    title: str
    description: str
    activity_type: str  # warmup, instruction, exercise, etc.
    estimated_minutes: int
    icon: str
    content_url: Optional[str] = None  # Link to learning unit
    subjects: Optional[List[str]] = None  # Faecher fuer die der Vorschlag passt (None = alle)
    grade_levels: Optional[List[str]] = None  # Klassenstufen (None = alle)

    def to_dict(self) -> Dict[str, Any]:
        """Konvertiert den Vorschlag in ein Dictionary."""
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "activity_type": self.activity_type,
            "estimated_minutes": self.estimated_minutes,
            "icon": self.icon,
            "content_url": self.content_url,
            "subjects": self.subjects,
            "grade_levels": self.grade_levels,
        }


# ==================== Homework Tracker (Feature f20) ====================

class HomeworkStatus(Enum):
    """Status einer Hausaufgabe."""
    ASSIGNED = "assigned"  # Aufgegeben
    IN_PROGRESS = "in_progress"  # In Bearbeitung
    COMPLETED = "completed"  # Erledigt
    OVERDUE = "overdue"  # Ueberfaellig


@dataclass
class Homework:
    """
    Eine Hausaufgabe (Feature f20).

    Ermoeglicht das Tracking von Hausaufgaben ueber Sessions hinweg.
    """
    homework_id: str
    teacher_id: str
    class_id: str
    subject: str
    title: str
    description: str = ""
    session_id: Optional[str] = None  # Verknuepfte Session
    due_date: Optional[datetime] = None
    status: HomeworkStatus = HomeworkStatus.ASSIGNED
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    def to_dict(self) -> Dict[str, Any]:
        """Konvertiert die Hausaufgabe in ein Dictionary."""
        return {
            "homework_id": self.homework_id,
            "teacher_id": self.teacher_id,
            "class_id": self.class_id,
            "subject": self.subject,
            "title": self.title,
            "description": self.description,
            "session_id": self.session_id,
            "due_date": self.due_date.isoformat() if self.due_date else None,
            "status": self.status.value,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "is_overdue": self.is_overdue,
        }

    @property
    def is_overdue(self) -> bool:
        """Prueft ob die Hausaufgabe ueberfaellig ist."""
        if not self.due_date:
            return False
        if self.status == HomeworkStatus.COMPLETED:
            return False
        return datetime.now() > self.due_date


# ==================== Phase Materials (Feature f19) ====================

class MaterialType(Enum):
    """Typ des Materials."""
    DOCUMENT = "document"  # PDF, Word, etc.
    LINK = "link"  # URL
    VIDEO = "video"  # Video-Link
    IMAGE = "image"  # Bild
    WORKSHEET = "worksheet"  # Arbeitsblatt
    PRESENTATION = "presentation"  # Praesentation
    OTHER = "other"


@dataclass
class PhaseMaterial:
    """
    Material fuer eine Unterrichtsphase (Feature f19).

    Ermoeglicht das Anhaengen von Dokumenten, Links und Medien
    an bestimmte Phasen einer Unterrichtsstunde.
    """
    material_id: str
    teacher_id: str
    title: str
    material_type: MaterialType = MaterialType.DOCUMENT
    url: Optional[str] = None  # URL oder Dateipfad
    description: str = ""
    phase: Optional[str] = None  # Phasen-ID (einstieg, erarbeitung, etc.)
    subject: str = ""
    grade_level: str = ""
    tags: List[str] = field(default_factory=list)
    is_public: bool = False  # Fuer Sharing mit anderen Lehrern
    usage_count: int = 0
    session_id: Optional[str] = None  # Verknuepfung mit einer Session
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None

    def to_dict(self) -> Dict[str, Any]:
        """Konvertiert das Material in ein Dictionary."""
        return {
            "material_id": self.material_id,
            "teacher_id": self.teacher_id,
            "title": self.title,
            "material_type": self.material_type.value,
            "url": self.url,
            "description": self.description,
            "phase": self.phase,
            "subject": self.subject,
            "grade_level": self.grade_level,
            "tags": self.tags,
            "is_public": self.is_public,
            "usage_count": self.usage_count,
            "session_id": self.session_id,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
        }
