"""Data models for Bakalari timetable."""

from dataclasses import dataclass, field
from enum import Enum


class TimetableType(Enum):
    """Type of timetable view."""
    PERMANENT = "Permanent"  # Staly rozvrh
    ACTUAL = "Actual"        # Aktualni tyden
    NEXT = "Next"            # Pristi tyden


class ChangeType(Enum):
    """Type of schedule change."""
    NONE = "none"
    ROOM_CHANGE = "room_change"      # zmena ucebny
    CANCELLED = "cancelled"          # odpada
    TRANSFERRED = "transferred"      # presunuta hodina
    SUBSTITUTE = "substitute"        # supluje
    OTHER = "other"                  # jina zmena


@dataclass
class LessonHour:
    """A lesson hour period definition."""
    slot: int           # 0-10
    caption: str        # "1", "2", etc.
    start_time: str     # "8:00"
    end_time: str       # "8:45"


@dataclass
class Lesson:
    """A single lesson in the timetable."""
    slot: int                           # 0-10 (lesson period)
    subject: str = ""                   
    subject_short: str = ""             
    teacher: str = ""                   
    room: str = ""                      
    group: str = ""                     # Group/class info
    theme: str = ""                     # Lesson topic
    change_info: str = ""               # Raw change description
    change_type: ChangeType = ChangeType.NONE
    is_day_off: bool = False            # day-item-volno
    day_off_text: str = ""              # "Pololetni prazdniny"
    
    @property
    def is_empty(self) -> bool:
        """Check if this is an empty slot."""
        return not self.subject and not self.is_day_off
    
    @property
    def has_change(self) -> bool:
        """Check if this lesson has any change."""
        return self.change_type != ChangeType.NONE
    
    @property
    def display_short(self) -> str:
        """Short display for grid cell."""
        if self.is_day_off:
            return "---"
        if self.is_empty:
            return ""
        return self.subject_short or self.subject[:3].upper()


@dataclass
class Day:
    """A day in the timetable with all lessons."""
    name: str                   # "Po", "Ut", "St", "Ct", "Pa"
    date: str = ""              # "27.1." or empty for permanent
    is_day_off: bool = False    # timetable-day-off
    day_off_text: str = ""      # "Pololetni prazdniny"
    lessons: list[Lesson] = field(default_factory=list)
    
    def get_lesson(self, slot: int) -> Lesson | None:
        """Get lesson for a specific slot."""
        for lesson in self.lessons:
            if lesson.slot == slot:
                return lesson
        return None


@dataclass
class Timetable:
    """Complete timetable data."""
    base_url: str                        # Base school URL
    timetable_type: TimetableType        # PERMANENT, ACTUAL, NEXT
    entity_type: str                     # "Class", "Teacher", "Room"
    entity_id: str                       # "2F", teacher ID, room ID
    days: list[Day] = field(default_factory=list)
    hours: list[LessonHour] = field(default_factory=list)  # From .bk-timetable-hours
    
    @property
    def type_display(self) -> str:
        """Human-readable type name in Czech."""
        return {
            TimetableType.PERMANENT: "Stálý rozvrh",
            TimetableType.ACTUAL: "Aktuální tyden",
            TimetableType.NEXT: "Příští tyden",
        }.get(self.timetable_type, str(self.timetable_type))
    
    def get_url(self, new_type: TimetableType | None = None) -> str:
        """Generate URL for this timetable or a different type."""
        tt_type = new_type or self.timetable_type
        return f"{self.base_url}/Timetable/Public/{tt_type.value}/{self.entity_type}/{self.entity_id}"
    
    def get_lesson(self, day_index: int, slot: int) -> Lesson | None:
        """Get lesson at specific day and slot."""
        if 0 <= day_index < len(self.days):
            return self.days[day_index].get_lesson(slot)
        return None
    
    def get_hour(self, slot: int) -> LessonHour | None:
        """Get lesson hour definition for a slot."""
        for hour in self.hours:
            if hour.slot == slot:
                return hour
        return None
    
    def get_time_range(self, slot: int) -> str:
        """Get time range string for a slot."""
        hour = self.get_hour(slot)
        if hour:
            return f"{hour.start_time} - {hour.end_time}"
        return ""
