"""
SQLAlchemy Database Models fuer Schuljahres-Kontext (Phase 8).

Erweitert das Companion-Modul um ein 2-Schichten-Modell:
- Makro-Ebene: 7 Schuljahres-Phasen (langsam wechselnd)
- Mikro-Ebene: Events, Routinen, Arbeitsmodi (tagesaktuell)
"""
from datetime import datetime, time
from sqlalchemy import (
    Column, String, Integer, DateTime, JSON,
    Boolean, Text, Enum as SQLEnum, Time
)
import enum
import uuid

from .database import Base

# Exports
__all__ = [
    "MacroPhaseEnum",
    "EventTypeEnum",
    "EventStatusEnum",
    "RoutineTypeEnum",
    "RecurrencePatternEnum",
    "TeacherContextDB",
    "SchoolyearEventDB",
    "RecurringRoutineDB",
    "FEDERAL_STATES",
    "SCHOOL_TYPES",
]


# ==================== Konstanten ====================

FEDERAL_STATES = {
    "BW": "Baden-Wuerttemberg",
    "BY": "Bayern",
    "BE": "Berlin",
    "BB": "Brandenburg",
    "HB": "Bremen",
    "HH": "Hamburg",
    "HE": "Hessen",
    "MV": "Mecklenburg-Vorpommern",
    "NI": "Niedersachsen",
    "NW": "Nordrhein-Westfalen",
    "RP": "Rheinland-Pfalz",
    "SL": "Saarland",
    "SN": "Sachsen",
    "ST": "Sachsen-Anhalt",
    "SH": "Schleswig-Holstein",
    "TH": "Thueringen",
}

SCHOOL_TYPES = {
    "grundschule": "Grundschule",
    "hauptschule": "Hauptschule",
    "realschule": "Realschule",
    "gymnasium": "Gymnasium",
    "gesamtschule": "Gesamtschule",
    "foerderschule": "Foerderschule",
    "berufsschule": "Berufsschule",
    "gemeinschaftsschule": "Gemeinschaftsschule",
}


# ==================== Enums ====================

class MacroPhaseEnum(str, enum.Enum):
    """
    7 Schuljahres-Phasen (Makro-State).

    Wechselt alle paar Wochen basierend auf Schulkalender und Nutzungsverhalten.
    """
    ONBOARDING = "onboarding"  # Ersteinrichtung (Klassen, Stundenplan)
    SCHULJAHRESSTART = "schuljahresstart"  # Erste 2-3 Wochen
    UNTERRICHTSAUFBAU = "unterrichtsaufbau"  # Routinen etablieren
    LEISTUNGSPHASE_1 = "leistungsphase_1"  # Erste Klausuren
    HALBJAHRESABSCHLUSS = "halbjahresabschluss"  # Notenschluss, Zeugnisse
    LEISTUNGSPHASE_2 = "leistungsphase_2"  # Pruefungsvorbereitung
    JAHRESABSCHLUSS = "jahresabschluss"  # Finale Noten, Versetzung


class EventTypeEnum(str, enum.Enum):
    """Event-Typen fuer Schuljahr-Events."""
    EXAM = "exam"  # Klassenarbeit, Klausur
    PARENT_EVENING = "parent_evening"  # Elternabend
    TRIP = "trip"  # Klassenfahrt, Ausflug
    PROJECT = "project"  # Projektwoche
    INTERNSHIP = "internship"  # Praktikum
    PRESENTATION = "presentation"  # Referate, Praesentationen
    SPORTS_DAY = "sports_day"  # Sporttag, Bundesjugendspiele
    SCHOOL_FESTIVAL = "school_festival"  # Schulfest
    PARENT_CONSULTATION = "parent_consultation"  # Elternsprechtag
    GRADE_DEADLINE = "grade_deadline"  # Notenschluss
    REPORT_CARDS = "report_cards"  # Zeugnisausgabe
    HOLIDAY_START = "holiday_start"  # Ferienbeginn
    HOLIDAY_END = "holiday_end"  # Ferienende
    OTHER = "other"


class EventStatusEnum(str, enum.Enum):
    """Status eines Events."""
    PLANNED = "planned"
    IN_PROGRESS = "in_progress"
    DONE = "done"
    CANCELLED = "cancelled"


class RoutineTypeEnum(str, enum.Enum):
    """Typen wiederkehrender Routinen."""
    TEACHER_CONFERENCE = "teacher_conference"  # Lehrerkonferenz
    SUBJECT_CONFERENCE = "subject_conference"  # Fachkonferenz
    OFFICE_HOURS = "office_hours"  # Sprechstunde
    TEAM_MEETING = "team_meeting"  # Teamsitzung
    SUPERVISION = "supervision"  # Pausenaufsicht
    CORRECTION_TIME = "correction_time"  # Korrekturzeit
    PREP_TIME = "prep_time"  # Vorbereitungszeit
    OTHER = "other"


class RecurrencePatternEnum(str, enum.Enum):
    """Wiederholungsmuster fuer Routinen."""
    DAILY = "daily"
    WEEKLY = "weekly"
    BIWEEKLY = "biweekly"
    MONTHLY = "monthly"


# ==================== Models ====================

class TeacherContextDB(Base):
    """
    Lehrer-Kontext fuer Schuljahres-Begleitung (Phase 8).

    Speichert den Makro-Kontext eines Lehrers:
    - Bundesland (fuer Schulkalender/Ferien)
    - Schulart
    - Aktuelles Schuljahr
    - Aktuelle Makro-Phase

    Ein Lehrer hat genau einen Context-Eintrag.
    """
    __tablename__ = 'teacher_contexts'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    teacher_id = Column(String(100), unique=True, nullable=False, index=True)

    # Schul-Kontext
    federal_state = Column(String(10), default="BY")  # BY, NRW, etc.
    school_type = Column(String(50), default="gymnasium")  # gymnasium, realschule, etc.

    # Schuljahr
    schoolyear = Column(String(20), default="2024-2025")  # z.B. "2024-2025"
    schoolyear_start = Column(DateTime, nullable=True)  # Erster Schultag

    # Aktueller Stand (Makro-Phase)
    macro_phase = Column(
        SQLEnum(MacroPhaseEnum),
        default=MacroPhaseEnum.ONBOARDING,
        nullable=False
    )
    current_week = Column(Integer, default=1)  # Schulwoche 1-52

    # Berechnete Flags (werden beim Abrufen aktualisiert)
    is_exam_period = Column(Boolean, default=False)
    is_before_holidays = Column(Boolean, default=False)

    # Onboarding-Status
    onboarding_completed = Column(Boolean, default=False)
    has_classes = Column(Boolean, default=False)
    has_schedule = Column(Boolean, default=False)

    # Metadaten
    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def __repr__(self):
        return f"<TeacherContext {self.teacher_id} ({self.macro_phase.value})>"


class SchoolyearEventDB(Base):
    """
    Schuljahr-Event (Phase 8).

    Ein einmaliges Event im Schuljahr wie:
    - Klassenarbeit
    - Elternabend
    - Klassenfahrt
    - Projektwoche

    Events haben einen Zeitraum und optionale Klassen-/Fach-Zuordnung.
    """
    __tablename__ = 'schoolyear_events'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    teacher_id = Column(String(100), nullable=False, index=True)

    # Event-Typ und Titel
    event_type = Column(
        SQLEnum(EventTypeEnum),
        default=EventTypeEnum.OTHER,
        nullable=False
    )
    title = Column(String(300), nullable=False)
    description = Column(Text, default="")

    # Zeitraum
    start_date = Column(DateTime, nullable=False, index=True)
    end_date = Column(DateTime, nullable=True)  # Null = eintaegiges Event

    # Optionale Zuordnung
    class_id = Column(String(100), nullable=True, index=True)
    subject = Column(String(100), nullable=True)

    # Status
    status = Column(
        SQLEnum(EventStatusEnum),
        default=EventStatusEnum.PLANNED,
        nullable=False,
        index=True
    )

    # Flags fuer Antizipation
    needs_preparation = Column(Boolean, default=True)  # Braucht Vorbereitung?
    preparation_done = Column(Boolean, default=False)  # Vorbereitung erledigt?
    reminder_days_before = Column(Integer, default=7)  # Tage vorher erinnern

    # Flexible Zusatzdaten (z.B. Rubric-ID fuer Klausur)
    extra_data = Column(JSON, default=dict)  # Renamed from 'metadata' which is reserved in SQLAlchemy

    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def __repr__(self):
        return f"<SchoolyearEvent {self.title} ({self.event_type.value})>"


class RecurringRoutineDB(Base):
    """
    Wiederkehrende Routine (Phase 8).

    Eine regelmaessig wiederkehrende Aktivitaet wie:
    - Lehrerkonferenz (woechentlich/monatlich)
    - Fachkonferenz
    - Sprechstunde
    - Korrekturzeit

    Routinen wiederholen sich nach einem bestimmten Muster.
    """
    __tablename__ = 'recurring_routines'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    teacher_id = Column(String(100), nullable=False, index=True)

    # Routine-Typ und Titel
    routine_type = Column(
        SQLEnum(RoutineTypeEnum),
        default=RoutineTypeEnum.OTHER,
        nullable=False
    )
    title = Column(String(300), nullable=False)
    description = Column(Text, default="")

    # Wiederholung
    recurrence_pattern = Column(
        SQLEnum(RecurrencePatternEnum),
        default=RecurrencePatternEnum.WEEKLY,
        nullable=False
    )
    day_of_week = Column(Integer, nullable=True)  # 0=Mo, 6=So (Null wenn daily/monthly)
    day_of_month = Column(Integer, nullable=True)  # 1-31 fuer monthly
    time_of_day = Column(Time, nullable=True)  # z.B. 14:00

    # Dauer in Minuten
    duration_minutes = Column(Integer, default=60)

    # Aktiv?
    is_active = Column(Boolean, default=True)

    # Startdatum (ab wann gilt die Routine?)
    valid_from = Column(DateTime, nullable=True)
    valid_until = Column(DateTime, nullable=True)

    # Metadaten
    extra_data = Column(JSON, default=dict)  # Renamed from 'metadata' which is reserved in SQLAlchemy

    created_at = Column(DateTime, default=datetime.utcnow)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)

    def __repr__(self):
        return f"<RecurringRoutine {self.title} ({self.recurrence_pattern.value})>"
