"""
SQLAlchemy Database Models fuer Classroom Engine (Feature f13).

Persistiert Unterrichtsstunden und deren Verlauf in PostgreSQL.
"""
from datetime import datetime
from sqlalchemy import (
    Column, String, Integer, Float, DateTime, JSON,
    Boolean, Text, Enum as SQLEnum, ForeignKey
)
from sqlalchemy.orm import relationship
import enum
import uuid

from .database import Base

# Import Phase 8 Context Models
from .context_models import (
    MacroPhaseEnum,
    EventTypeEnum,
    EventStatusEnum,
    RoutineTypeEnum,
    RecurrencePatternEnum,
    TeacherContextDB,
    SchoolyearEventDB,
    RecurringRoutineDB,
    FEDERAL_STATES,
    SCHOOL_TYPES,
)

# Exports
__all__ = [
    "LessonPhaseEnum",
    "LessonSessionDB",
    "PhaseHistoryDB",
    "LessonTemplateDB",
    "TeacherSettingsDB",
    "HomeworkStatusEnum",
    "HomeworkDB",
    "MaterialTypeEnum",
    "PhaseMaterialDB",
    "LessonReflectionDB",
    "FeedbackTypeEnum",
    "FeedbackStatusEnum",
    "FeedbackPriorityEnum",
    "TeacherFeedbackDB",
    # Phase 8: Schuljahres-Kontext
    "MacroPhaseEnum",
    "EventTypeEnum",
    "EventStatusEnum",
    "RoutineTypeEnum",
    "RecurrencePatternEnum",
    "TeacherContextDB",
    "SchoolyearEventDB",
    "RecurringRoutineDB",
    "FEDERAL_STATES",
    "SCHOOL_TYPES",
]


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


class LessonSessionDB(Base):
    """
    Persistierte Unterrichtsstunde.

    Speichert alle Session-Daten inklusive Timer-Status und History.
    """
    __tablename__ = 'lesson_sessions'

    # Primary Key
    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))

    # Beziehungen
    teacher_id = Column(String(100), nullable=False, index=True)
    class_id = Column(String(50), nullable=False, index=True)

    # Session Metadaten
    subject = Column(String(100), nullable=False)
    topic = Column(String(500))

    # Status
    current_phase = Column(
        SQLEnum(LessonPhaseEnum),
        default=LessonPhaseEnum.NOT_STARTED,
        nullable=False
    )
    is_paused = Column(Boolean, default=False)

    # Timestamps
    created_at = Column(DateTime, default=datetime.utcnow)
    lesson_started_at = Column(DateTime)
    lesson_ended_at = Column(DateTime)
    phase_started_at = Column(DateTime)
    pause_started_at = Column(DateTime)

    # Timer-Daten
    total_paused_seconds = Column(Integer, default=0)
    phase_durations = Column(JSON, default=dict)  # {"einstieg": 8, ...}

    # History & Notizen
    phase_history = Column(JSON, default=list)  # [{phase, started_at, ended_at, duration}]
    notes = Column(Text, default="")
    homework = Column(Text, default="")

    # Relationship zu PhaseHistory (optional fuer detaillierte Abfragen)
    history_entries = relationship("PhaseHistoryDB", back_populates="session", cascade="all, delete-orphan")

    def __repr__(self):
        return f"<LessonSession {self.id}: {self.subject} ({self.current_phase.value})>"


class PhaseHistoryDB(Base):
    """
    Einzelner Phasen-Verlaufseintrag.

    Ermoeglicht detaillierte Statistiken ueber Phasendauern.
    """
    __tablename__ = 'lesson_phase_history'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    session_id = Column(String(36), ForeignKey('lesson_sessions.id'), nullable=False, index=True)

    phase = Column(SQLEnum(LessonPhaseEnum), nullable=False)
    started_at = Column(DateTime, nullable=False)
    ended_at = Column(DateTime)
    duration_seconds = Column(Integer)

    # Zusaetzliche Metriken
    was_extended = Column(Boolean, default=False)
    extension_minutes = Column(Integer, default=0)
    pause_count = Column(Integer, default=0)
    total_pause_seconds = Column(Integer, default=0)

    # Relationship
    session = relationship("LessonSessionDB", back_populates="history_entries")

    def __repr__(self):
        return f"<PhaseHistory {self.phase.value} ({self.duration_seconds}s)>"


class LessonTemplateDB(Base):
    """
    Stunden-Vorlage (Feature f37).

    Ermoeglicht Speicherung von wiederverwendbaren Stundenkonfigurationen.
    """
    __tablename__ = 'lesson_templates'

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

    # Basis-Infos
    name = Column(String(200), nullable=False)
    description = Column(Text, default="")
    subject = Column(String(100), default="")
    grade_level = Column(String(50), default="")

    # Phasenkonfiguration
    phase_durations = Column(JSON, default=dict)

    # Vorbelegungen
    default_topic = Column(String(500), default="")
    default_notes = Column(Text, default="")

    # Metadaten
    is_public = Column(Boolean, default=False)
    usage_count = Column(Integer, default=0)

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

    def __repr__(self):
        return f"<LessonTemplate {self.name} ({self.teacher_id})>"


class TeacherSettingsDB(Base):
    """
    Lehrer-spezifische Einstellungen (Feature f16).

    Speichert individuelle Praeferenzen wie Phasendauern.
    """
    __tablename__ = 'teacher_settings'

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

    # Individuelle Phasendauern
    default_phase_durations = Column(JSON, default=dict)

    # UI Praeferenzen
    audio_enabled = Column(Boolean, default=True)
    high_contrast = Column(Boolean, default=False)

    # Statistik-Einstellungen
    show_statistics = Column(Boolean, default=True)

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

    def __repr__(self):
        return f"<TeacherSettings {self.teacher_id}>"


class HomeworkStatusEnum(str, enum.Enum):
    """Status-Enum fuer Hausaufgaben."""
    ASSIGNED = "assigned"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    OVERDUE = "overdue"


class HomeworkDB(Base):
    """
    Hausaufgaben-Tracking (Feature f20).

    Ermoeglicht die Verfolgung von Hausaufgaben ueber Sessions hinweg.
    """
    __tablename__ = 'homework_assignments'

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

    # Aufgaben-Details
    title = Column(String(300), nullable=False)
    description = Column(Text, default="")

    # Verknuepfung zur Session (optional)
    session_id = Column(String(36), ForeignKey('lesson_sessions.id'), nullable=True, index=True)

    # Faelligkeit und Status
    due_date = Column(DateTime, nullable=True, index=True)
    status = Column(
        SQLEnum(HomeworkStatusEnum),
        default=HomeworkStatusEnum.ASSIGNED,
        nullable=False
    )

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

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


class MaterialTypeEnum(str, enum.Enum):
    """Typ-Enum fuer Materialien."""
    DOCUMENT = "document"
    LINK = "link"
    VIDEO = "video"
    IMAGE = "image"
    WORKSHEET = "worksheet"
    PRESENTATION = "presentation"
    OTHER = "other"


class PhaseMaterialDB(Base):
    """
    Phasen-Materialien (Feature f19).

    Ermoeglicht das Anhaengen von Dokumenten und Links an Unterrichtsphasen.
    """
    __tablename__ = 'phase_materials'

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

    # Material-Details
    title = Column(String(300), nullable=False)
    material_type = Column(
        SQLEnum(MaterialTypeEnum),
        default=MaterialTypeEnum.DOCUMENT,
        nullable=False
    )
    url = Column(String(2000), nullable=True)  # URL oder Dateipfad
    description = Column(Text, default="")

    # Phasen-Zuordnung
    phase = Column(String(50), nullable=True, index=True)  # einstieg, erarbeitung, etc.
    subject = Column(String(100), default="")
    grade_level = Column(String(50), default="")

    # Tags als JSON Array
    tags = Column(JSON, default=list)

    # Sharing und Nutzung
    is_public = Column(Boolean, default=False)
    usage_count = Column(Integer, default=0)

    # Optionale Session-Verknuepfung
    session_id = Column(String(36), ForeignKey('lesson_sessions.id'), nullable=True, index=True)

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

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


class LessonReflectionDB(Base):
    """
    Post-Lesson Reflection (Phase 5: Analytics).

    Ermoeglicht Lehrern, nach der Stunde Reflexionsnotizen zu speichern.
    """
    __tablename__ = 'lesson_reflections'

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

    # Reflexions-Inhalt
    notes = Column(Text, default="")

    # Optionale Selbst-Bewertung (1-5)
    overall_rating = Column(Integer, nullable=True)

    # Was hat gut funktioniert? (JSON Array)
    what_worked = Column(JSON, default=list)

    # Was wuerde ich anders machen? (JSON Array)
    improvements = Column(JSON, default=list)

    # Notizen fuer naechste Stunde
    notes_for_next_lesson = Column(Text, default="")

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

    def __repr__(self):
        return f"<LessonReflection session={self.session_id}>"


class FeedbackTypeEnum(str, enum.Enum):
    """Feedback-Typen fuer Lehrer-Rueckmeldungen."""
    BUG = "bug"
    FEATURE_REQUEST = "feature_request"
    IMPROVEMENT = "improvement"
    PRAISE = "praise"
    QUESTION = "question"


class FeedbackStatusEnum(str, enum.Enum):
    """Status eines Feedbacks."""
    NEW = "new"
    ACKNOWLEDGED = "acknowledged"
    PLANNED = "planned"
    IMPLEMENTED = "implemented"
    DECLINED = "declined"


class FeedbackPriorityEnum(str, enum.Enum):
    """Prioritaet eines Feedbacks."""
    CRITICAL = "critical"
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


class TeacherFeedbackDB(Base):
    """
    Lehrer-Feedback zum Companion-Modul (Phase 7).

    Ermoeglicht Lehrern, Bug-Reports, Feature-Requests und Verbesserungen
    direkt aus dem Lehrer-Frontend zu senden.
    """
    __tablename__ = 'teacher_feedback'

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))

    # Wer hat das Feedback gegeben?
    teacher_id = Column(String(100), nullable=False, index=True)
    teacher_name = Column(String(200), default="")
    teacher_email = Column(String(200), default="")

    # Feedback-Inhalt
    title = Column(String(500), nullable=False)
    description = Column(Text, nullable=False)

    # Kategorisierung
    feedback_type = Column(
        SQLEnum(FeedbackTypeEnum),
        default=FeedbackTypeEnum.IMPROVEMENT,
        nullable=False
    )
    priority = Column(
        SQLEnum(FeedbackPriorityEnum),
        default=FeedbackPriorityEnum.MEDIUM,
        nullable=False
    )
    status = Column(
        SQLEnum(FeedbackStatusEnum),
        default=FeedbackStatusEnum.NEW,
        nullable=False,
        index=True
    )

    # Optionale Verknuepfung zu Feature
    related_feature = Column(String(50), nullable=True)

    # Kontext: Wo war der User als er Feedback gab?
    context_url = Column(String(500), default="")
    context_phase = Column(String(50), default="")  # z.B. "einstieg"
    context_session_id = Column(String(36), nullable=True)

    # Browser/Device Info
    user_agent = Column(String(500), default="")

    # Entwickler-Antwort
    response = Column(Text, default="")
    responded_at = Column(DateTime, nullable=True)
    responded_by = Column(String(100), nullable=True)

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

    def __repr__(self):
        return f"<TeacherFeedback {self.id[:8]} - {self.title[:30]}>"
