"""
Модели расписания занятий.
"""
from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator, FileExtensionValidator
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
from datetime import timedelta
import uuid
import os


class Subject(models.Model):
    """
    Модель предмета обучения.
    Общие предметы, доступные всем менторам.
    """
    name = models.CharField(
        max_length=100,
        unique=True,
        verbose_name='Название предмета',
        help_text='Название предмета обучения'
    )
    
    is_active = models.BooleanField(
        default=True,
        verbose_name='Активен',
        help_text='Доступен ли предмет для использования'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'subjects'
        verbose_name = 'Предмет'
        verbose_name_plural = 'Предметы'
        ordering = ['name']
        indexes = [
            models.Index(fields=['is_active', 'name']),
        ]
    
    def __str__(self):
        return self.name


class MentorSubject(models.Model):
    """
    Кастомный предмет ментора.
    Используется для предметов, которые еще не добавлены в общую модель Subject.
    Если предмет используется более чем 10 менторами, он должен быть перенесен в Subject.
    """
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='mentor_subjects',
        limit_choices_to={'role': 'mentor'},
        verbose_name='Ментор'
    )
    
    name = models.CharField(
        max_length=100,
        verbose_name='Название предмета',
        help_text='Название кастомного предмета'
    )
    
    usage_count = models.IntegerField(
        default=0,
        verbose_name='Количество использований',
        help_text='Сколько раз этот предмет был использован в занятиях'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'mentor_subjects'
        verbose_name = 'Предмет ментора'
        verbose_name_plural = 'Предметы менторов'
        ordering = ['mentor', 'name']
        indexes = [
            models.Index(fields=['mentor', 'name']),
            models.Index(fields=['name', 'usage_count']),
        ]
        constraints = [
            models.UniqueConstraint(
                fields=['mentor', 'name'],
                name='unique_mentor_subject'
            ),
        ]
    
    def __str__(self):
        return f"{self.name} ({self.mentor.get_full_name()})"
    
    def increment_usage(self):
        """Увеличить счетчик использования."""
        self.usage_count += 1
        self.save(update_fields=['usage_count', 'updated_at'])


class Lesson(models.Model):
    """
    Модель занятия.
    Представляет конкретное занятие в определенное время.
    """
    
    STATUS_CHOICES = [
        ('scheduled', 'Запланировано'),
        ('in_progress', 'В процессе'),
        ('completed', 'Завершено'),
        ('cancelled', 'Отменено'),
        ('rescheduled', 'Перенесено'),
    ]
    
    # Участники
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='mentor_lessons',
        limit_choices_to={'role': 'mentor'},
        verbose_name='Ментор'
    )
    
    client = models.ForeignKey(
        'users.Client',
        on_delete=models.CASCADE,
        related_name='lessons',
        verbose_name='Клиент'
    )
    
    # Время и продолжительность
    start_time = models.DateTimeField(
        verbose_name='Время начала',
        db_index=True
    )
    
    end_time = models.DateTimeField(
        verbose_name='Время окончания',
        db_index=True
    )
    
    duration = models.IntegerField(
        validators=[MinValueValidator(15), MaxValueValidator(480)],
        default=60,
        verbose_name='Длительность (минуты)',
        help_text='Длительность занятия в минутах (15-480)'
    )
    
    # Информация о занятии
    title = models.CharField(
        max_length=200,
        verbose_name='Название',
        help_text='Краткое название занятия'
    )
    
    description = models.TextField(
        blank=True,
        verbose_name='Описание',
        help_text='Подробное описание занятия'
    )
    
    # Предмет (может быть общим или кастомным)
    subject = models.ForeignKey(
        'Subject',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='lessons',
        verbose_name='Предмет',
        help_text='Общий предмет обучения'
    )
    
    # Кастомный предмет ментора (если не выбран общий предмет)
    mentor_subject = models.ForeignKey(
        'MentorSubject',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='lessons',
        verbose_name='Кастомный предмет',
        help_text='Кастомный предмет ментора (если не выбран общий предмет)'
    )
    
    # Для обратной совместимости - храним название предмета как строку
    subject_name = models.CharField(
        max_length=100,
        blank=True,
        verbose_name='Название предмета (legacy)',
        help_text='Название предмета для обратной совместимости'
    )
    
    # Статус
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='scheduled',
        verbose_name='Статус',
        db_index=True
    )
    
    # Связь с шаблоном (если создано из шаблона)
    template = models.ForeignKey(
        'LessonTemplate',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='lessons',
        verbose_name='Шаблон'
    )
    
    # Отмена
    cancelled_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='cancelled_lessons',
        verbose_name='Отменено пользователем'
    )
    
    cancellation_reason = models.TextField(
        blank=True,
        verbose_name='Причина отмены'
    )
    
    cancelled_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Дата отмены'
    )
    
    # Перенос
    rescheduled_from = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='rescheduled_to',
        verbose_name='Перенесено из'
    )
    
    # Ссылки
    meeting_url = models.URLField(
        blank=True,
        max_length=500,
        verbose_name='Ссылка на встречу',
        help_text='Ссылка на видеоконференцию'
    )
    
    # Заметки
    mentor_notes = models.TextField(
        blank=True,
        verbose_name='Заметки ментора',
        help_text='Приватные заметки ментора о занятии'
    )
    
    # Домашнее задание
    homework_text = models.TextField(
        blank=True,
        verbose_name='Домашнее задание',
        help_text='Описание домашнего задания, выданного по результатам занятия'
    )
    
    # Оценки
    mentor_grade = models.IntegerField(
        null=True,
        blank=True,
        verbose_name='Оценка ментора',
        help_text='Оценка работы студента на занятии (0-100)'
    )
    
    school_grade = models.IntegerField(
        null=True,
        blank=True,
        verbose_name='Оценка в школе',
        help_text='Текущая оценка студента в школе (0-100)'
    )
    
    # Стоимость
    price = models.DecimalField(
        max_digits=10,
        decimal_places=2,
        null=True,
        blank=True,
        verbose_name='Стоимость',
        help_text='Стоимость занятия в рублях'
    )

    # Группа (для групповых занятий)
    group = models.ForeignKey(
        'users.Group',
        on_delete=models.SET_NULL,
        related_name='lessons',
        null=True,
        blank=True,
        verbose_name='Группа',
        help_text='Учебная группа, если занятие групповое'
    )
    
    # Напоминания
    reminder_sent = models.BooleanField(
        default=False,
        verbose_name='Напоминание отправлено',
        help_text='Устаревшее поле, используйте reminder_24h_sent, reminder_1h_sent, reminder_15m_sent'
    )
    
    reminder_24h_sent = models.BooleanField(
        default=False,
        verbose_name='Напоминание за 24 часа отправлено',
        help_text='Отправлено ли напоминание за 24 часа до занятия'
    )
    
    reminder_1h_sent = models.BooleanField(
        default=False,
        verbose_name='Напоминание за 1 час отправлено',
        help_text='Отправлено ли напоминание за 1 час до занятия'
    )
    
    reminder_15m_sent = models.BooleanField(
        default=False,
        verbose_name='Напоминание за 15 минут отправлено',
        help_text='Отправлено ли напоминание за 15 минут до занятия'
    )
    
    # Подтверждение присутствия
    attendance_confirmation_sent = models.BooleanField(
        default=False,
        verbose_name='Запрос подтверждения присутствия отправлен',
        help_text='Отправлен ли запрос о подтверждении присутствия за 3 часа до занятия'
    )
    
    attendance_confirmed = models.BooleanField(
        null=True,
        blank=True,
        verbose_name='Присутствие подтверждено',
        help_text='Ответ студента на запрос о присутствии (True - будет, False - не будет, None - не ответил)'
    )
    
    attendance_response_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Время ответа о присутствии'
    )
    
    # reminder_sent_at временно удалено из модели, так как было удалено в миграции 0004
    # TODO: Добавить обратно при необходимости
    # reminder_sent_at = models.DateTimeField(
    #     null=True,
    #     blank=True,
    #     verbose_name='Время отправки напоминания'
    # )
    
    # Метрики подключения к видеокомнате (заполняются при подключении ментора/студента)
    mentor_connected_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Ментор подключился',
        help_text='Время подключения ментора к видеокомнате'
    )
    client_connected_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Студент подключился',
        help_text='Время подключения студента к видеокомнате'
    )
    
    # Фактическое время завершения (если занятие завершено досрочно)
    completed_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Фактическое время завершения',
        help_text='Время, когда занятие было фактически завершено (может отличаться от end_time)'
    )
    
    # LiveKit видеоконференция
    livekit_room_name = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Название LiveKit комнаты',
        help_text='Уникальное название комнаты LiveKit для этого занятия',
        db_index=True
    )
    
    livekit_access_token = models.TextField(
        blank=True,
        verbose_name='Токен доступа LiveKit',
        help_text='JWT токен для подключения к LiveKit комнате (действителен 24 часа)'
    )
    
    # Повторяющиеся занятия
    is_recurring = models.BooleanField(
        default=False,
        verbose_name='Постоянное время занятия',
        help_text='Если отмечено, занятие будет повторяться каждую неделю в этот день и время'
    )
    
    recurring_series_id = models.UUIDField(
        null=True,
        blank=True,
        verbose_name='ID серии повторяющихся занятий',
        help_text='Уникальный ID для группировки занятий одной серии',
        db_index=True
    )
    
    parent_lesson = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='recurring_lessons',
        verbose_name='Родительское занятие',
        help_text='Ссылка на первое занятие в серии повторяющихся занятий'
    )
    
    # Временные метки
    created_at = models.DateTimeField(
        auto_now_add=True,
        null=True,
        blank=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'lessons'
        verbose_name = 'Занятие'
        verbose_name_plural = 'Занятия'
        ordering = ['start_time']
        indexes = [
            models.Index(fields=['mentor', 'start_time']),
            models.Index(fields=['client', 'start_time']),
            models.Index(fields=['status', 'start_time']),
            models.Index(fields=['start_time', 'end_time']),
            models.Index(fields=['recurring_series_id']),
            models.Index(fields=['mentor', 'status']),
            models.Index(fields=['subject']),
            models.Index(fields=['created_at']),
        ]
        constraints = [
            models.CheckConstraint(
                check=models.Q(end_time__gt=models.F('start_time')),
                name='lesson_end_after_start'
            ),
        ]
    
    def __str__(self):
        return f"{self.title} - {self.client.user.get_full_name()} ({self.start_time.strftime('%d.%m.%Y %H:%M')})"
    
    def save(self, *args, **kwargs):
        """Автоматический расчет end_time на основе start_time и duration."""
        if self.start_time and self.duration:
            self.end_time = self.start_time + timedelta(minutes=self.duration)
        super().save(*args, **kwargs)
    
    @property
    def is_upcoming(self):
        """Проверка, является ли занятие предстоящим."""
        return self.start_time > timezone.now() and self.status == 'scheduled'
    
    @property
    def is_past(self):
        """Проверка, прошло ли занятие."""
        return self.end_time < timezone.now()
    
    @property
    def is_in_progress(self):
        """Проверка, идет ли занятие сейчас."""
        now = timezone.now()
        return self.start_time <= now <= self.end_time and self.status == 'in_progress'
    
    @property
    def can_be_cancelled(self):
        """Можно ли отменить занятие."""
        return self.status in ['scheduled'] and self.start_time > timezone.now()
    
    @property
    def can_be_rescheduled(self):
        """Можно ли перенести занятие."""
        return self.status in ['scheduled'] and self.start_time > timezone.now()
    
    def cancel(self, user, reason=''):
        """Отменить занятие."""
        if not self.can_be_cancelled:
            raise ValueError('Занятие нельзя отменить')
        
        self.status = 'cancelled'
        self.cancelled_by = user
        self.cancellation_reason = reason
        self.cancelled_at = timezone.now()
        self.save()
    
    def reschedule(self, new_start_time):
        """Перенести занятие на новое время."""
        if not self.can_be_rescheduled:
            raise ValueError('Занятие нельзя перенести')
        
        # Создаем новое занятие
        new_lesson = Lesson.objects.create(
            mentor=self.mentor,
            client=self.client,
            start_time=new_start_time,
            duration=self.duration,
            title=self.title,
            description=self.description,
            subject=self.subject,
            mentor_subject=self.mentor_subject,
            subject_name=self.subject_name or (self.subject.name if self.subject else '') or (self.mentor_subject.name if self.mentor_subject else ''),
            template=self.template,
            meeting_url=self.meeting_url,
            rescheduled_from=self,
        )
        
        # Отмечаем старое как перенесенное
        self.status = 'rescheduled'
        self.save()
        
        return new_lesson


class LessonTemplate(models.Model):
    """
    Шаблон занятия.
    Используется для быстрого создания повторяющихся занятий.
    """
    
    # Владелец шаблона
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='lesson_templates',
        limit_choices_to={'role': 'mentor'},
        verbose_name='Ментор'
    )
    
    # Информация о шаблоне
    title = models.CharField(
        max_length=200,
        verbose_name='Название'
    )
    
    description = models.TextField(
        blank=True,
        verbose_name='Описание'
    )
    
    subject = models.ForeignKey(
        'Subject',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='templates',
        verbose_name='Предмет'
    )
    
    mentor_subject = models.ForeignKey(
        'MentorSubject',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='templates',
        verbose_name='Кастомный предмет'
    )
    
    subject_name = models.CharField(
        max_length=100,
        blank=True,
        verbose_name='Название предмета (legacy)'
    )
    
    duration = models.IntegerField(
        validators=[MinValueValidator(15), MaxValueValidator(480)],
        default=60,
        verbose_name='Длительность (минуты)'
    )
    
    # Настройки
    is_active = models.BooleanField(
        default=True,
        verbose_name='Активен'
    )
    
    meeting_url = models.URLField(
        blank=True,
        max_length=500,
        verbose_name='Ссылка на встречу'
    )
    
    # Цвет для календаря
    color = models.CharField(
        max_length=7,
        default='#3B82F6',
        verbose_name='Цвет',
        help_text='HEX код цвета для отображения в календаре'
    )
    
    # Временные метки
    created_at = models.DateTimeField(
        auto_now_add=True,
        null=True,
        blank=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'lesson_templates'
        verbose_name = 'Шаблон занятия'
        verbose_name_plural = 'Шаблоны занятий'
        ordering = ['mentor', 'title']
    
    def __str__(self):
        return f"{self.title} ({self.mentor.get_full_name()})"
    
    def create_lesson(self, client, start_time):
        """Создать занятие из шаблона."""
        return Lesson.objects.create(
            mentor=self.mentor,
            client=client,
            start_time=start_time,
            duration=self.duration,
            title=self.title,
            description=self.description,
            subject=self.subject,
            mentor_subject=self.mentor_subject,
            subject_name=self.subject_name or (self.subject.name if self.subject else '') or (self.mentor_subject.name if self.mentor_subject else ''),
            template=self,
            meeting_url=self.meeting_url,
        )


class TimeSlot(models.Model):
    """
    Временной слот.
    Представляет конкретный временной интервал для бронирования.
    """
    
    # Ментор
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='time_slots',
        limit_choices_to={'role': 'mentor'},
        verbose_name='Ментор'
    )
    
    # Время
    start_time = models.DateTimeField(
        verbose_name='Время начала',
        db_index=True
    )
    
    end_time = models.DateTimeField(
        verbose_name='Время окончания',
        db_index=True
    )
    
    # Статус
    is_available = models.BooleanField(
        default=True,
        verbose_name='Доступен',
        help_text='Свободен ли слот для бронирования'
    )
    
    is_booked = models.BooleanField(
        default=False,
        verbose_name='Забронирован'
    )
    
    # Связь с занятием (если забронирован)
    lesson = models.OneToOneField(
        'Lesson',
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='time_slot',
        verbose_name='Занятие'
    )
    
    # Повторяющийся слот
    is_recurring = models.BooleanField(
        default=False,
        verbose_name='Повторяющийся',
        help_text='Повторяется ли этот слот еженедельно'
    )
    
    recurring_day = models.IntegerField(
        null=True,
        blank=True,
        validators=[MinValueValidator(0), MaxValueValidator(6)],
        verbose_name='День недели',
        help_text='0=Понедельник, 6=Воскресенье'
    )
    
    # Временные метки
    created_at = models.DateTimeField(
        auto_now_add=True,
        null=True,
        blank=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'time_slots'
        verbose_name = 'Временной слот'
        verbose_name_plural = 'Временные слоты'
        ordering = ['start_time']
        indexes = [
            models.Index(fields=['mentor', 'start_time']),
            models.Index(fields=['is_available', 'is_booked']),
            models.Index(fields=['start_time', 'end_time']),
        ]
        constraints = [
            models.CheckConstraint(
                check=models.Q(end_time__gt=models.F('start_time')),
                name='timeslot_end_after_start'
            ),
        ]
    
    def __str__(self):
        return f"{self.mentor.get_full_name()} - {self.start_time.strftime('%d.%m.%Y %H:%M')}-{self.end_time.strftime('%H:%M')}"
    
    def book(self, lesson):
        """Забронировать слот для занятия."""
        if self.is_booked:
            raise ValueError('Слот уже забронирован')
        if not self.is_available:
            raise ValueError('Слот недоступен')
        
        self.is_booked = True
        self.lesson = lesson
        self.save()
    
    def release(self):
        """Освободить слот."""
        self.is_booked = False
        self.lesson = None
        self.save()


class Availability(models.Model):
    """
    Доступность ментора.
    Определяет когда ментор доступен для занятий.
    """
    
    DAY_CHOICES = [
        (0, 'Понедельник'),
        (1, 'Вторник'),
        (2, 'Среда'),
        (3, 'Четверг'),
        (4, 'Пятница'),
        (5, 'Суббота'),
        (6, 'Воскресенье'),
    ]
    
    # Ментор
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='availabilities',
        limit_choices_to={'role': 'mentor'},
        verbose_name='Ментор'
    )
    
    # День недели (для повторяющейся доступности)
    day_of_week = models.IntegerField(
        choices=DAY_CHOICES,
        null=True,
        blank=True,
        verbose_name='День недели',
        help_text='Для еженедельного повторения'
    )
    
    # Конкретная дата (для разовой доступности)
    specific_date = models.DateField(
        null=True,
        blank=True,
        verbose_name='Конкретная дата',
        help_text='Для разовой доступности'
    )
    
    # Время
    start_time = models.TimeField(
        verbose_name='Время начала'
    )
    
    end_time = models.TimeField(
        verbose_name='Время окончания'
    )
    
    # Тип
    is_recurring = models.BooleanField(
        default=True,
        verbose_name='Повторяющаяся',
        help_text='Повторяется ли еженедельно'
    )
    
    # Статус
    is_active = models.BooleanField(
        default=True,
        verbose_name='Активна'
    )
    
    # Исключения (даты, когда доступность не действует)
    exception_dates = models.JSONField(
        default=list,
        blank=True,
        verbose_name='Даты исключений',
        help_text='Список дат в формате YYYY-MM-DD'
    )
    
    # Заметки
    notes = models.TextField(
        blank=True,
        verbose_name='Заметки'
    )
    
    # Временные метки
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'availabilities'
        verbose_name = 'Доступность'
        verbose_name_plural = 'Доступность'
        ordering = ['mentor', 'day_of_week', 'start_time']
        indexes = [
            models.Index(fields=['mentor', 'is_active']),
            models.Index(fields=['day_of_week', 'start_time']),
            models.Index(fields=['specific_date']),
        ]
        constraints = [
            models.CheckConstraint(
                check=models.Q(end_time__gt=models.F('start_time')),
                name='availability_end_after_start'
            ),
        ]
    
    def __str__(self):
        if self.is_recurring:
            day_name = dict(self.DAY_CHOICES)[self.day_of_week]
            return f"{self.mentor.get_full_name()} - {day_name} {self.start_time.strftime('%H:%M')}-{self.end_time.strftime('%H:%M')}"
        else:
            return f"{self.mentor.get_full_name()} - {self.specific_date} {self.start_time.strftime('%H:%M')}-{self.end_time.strftime('%H:%M')}"
    
    def is_available_on(self, date):
        """Проверка доступности на конкретную дату."""
        if not self.is_active:
            return False
        
        # Проверка исключений
        date_str = date.strftime('%Y-%m-%d')
        if date_str in self.exception_dates:
            return False
        
        # Проверка для повторяющейся доступности
        if self.is_recurring:
            return date.weekday() == self.day_of_week
        
        # Проверка для разовой доступности
        return date == self.specific_date


def lesson_file_upload_path(instance, filename):
    """Путь для загрузки файлов уроков."""
    ext = filename.split('.')[-1]
    new_filename = f"{uuid.uuid4()}.{ext}"
    return os.path.join('lessons', str(instance.lesson.id), new_filename)


class LessonFile(models.Model):
    """
    Файлы, прикрепленные к уроку.
    Могут быть загружены при завершении урока или выбраны из учебных материалов.
    """
    
    SOURCE_CHOICES = [
        ('uploaded', 'Загружен при завершении'),
        ('material', 'Из учебных материалов'),
    ]
    
    lesson = models.ForeignKey(
        Lesson,
        on_delete=models.CASCADE,
        related_name='files',
        verbose_name='Урок'
    )
    
    # Файл (если загружен)
    file = models.FileField(
        upload_to=lesson_file_upload_path,
        blank=True,
        null=True,
        max_length=500,
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx', 'txt', 'jpg', 'jpeg', 'png', 'zip', 'rar'])],
        verbose_name='Файл'
    )
    
    # Ссылка на материал (если выбран из материалов)
    material = models.ForeignKey(
        'materials.Material',
        on_delete=models.SET_NULL,
        related_name='lesson_files',
        null=True,
        blank=True,
        verbose_name='Учебный материал'
    )
    
    source = models.CharField(
        max_length=20,
        choices=SOURCE_CHOICES,
        default='uploaded',
        verbose_name='Источник'
    )
    
    filename = models.CharField(
        max_length=255,
        verbose_name='Название файла'
    )
    
    file_size = models.BigIntegerField(
        null=True,
        blank=True,
        verbose_name='Размер файла (bytes)'
    )
    
    description = models.TextField(
        blank=True,
        verbose_name='Описание'
    )
    
    uploaded_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='uploaded_lesson_files',
        null=True,
        verbose_name='Загрузил'
    )
    
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )
    
    class Meta:
        db_table = 'lesson_files'
        verbose_name = 'Файл урока'
        verbose_name_plural = 'Файлы уроков'
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['lesson']),
            models.Index(fields=['material']),
        ]
    
    def __str__(self):
        return f"{self.filename} - {self.lesson.title}"
    
    def get_file_url(self):
        """Получить URL файла."""
        if self.file:
            return self.file.url
        elif self.material and self.material.file:
            return self.material.file.url
        return None
    
    def get_file_size_display(self):
        """Отформатированный размер файла."""
        if not self.file_size:
            return '0 B'
        
        for unit in ['B', 'KB', 'MB', 'GB']:
            if self.file_size < 1024.0:
                return f"{self.file_size:.1f} {unit}"
            self.file_size /= 1024.0
        return f"{self.file_size:.1f} TB"


def lesson_homework_submission_file_path(instance, filename):
    """Путь для загрузки файлов ответов на ДЗ по уроку."""
    ext = filename.split('.')[-1]
    new_filename = f"{uuid.uuid4()}.{ext}"
    return os.path.join('lessons', str(instance.lesson.id), 'homework_submissions', new_filename)


class LessonHomeworkSubmission(models.Model):
    """
    Ответ ученика на домашнее задание по уроку.
    """
    
    STATUS_CHOICES = [
        ('pending', 'Ожидает проверки'),
        ('graded', 'Проверено'),
        ('returned', 'Возвращено на доработку'),
    ]
    
    lesson = models.ForeignKey(
        Lesson,
        on_delete=models.CASCADE,
        related_name='homework_submissions',
        verbose_name='Урок'
    )
    
    student = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='lesson_homework_submissions',
        limit_choices_to={'role': 'client'},
        verbose_name='Ученик'
    )
    
    # Содержимое ответа
    content = models.TextField(
        blank=True,
        verbose_name='Текст ответа',
        help_text='Текстовый ответ на домашнее задание'
    )
    
    # Файл ответа
    attachment = models.FileField(
        upload_to=lesson_homework_submission_file_path,
        blank=True,
        null=True,
        max_length=500,
        validators=[FileExtensionValidator(allowed_extensions=['pdf', 'doc', 'docx', 'txt', 'jpg', 'jpeg', 'png', 'zip', 'rar'])],
        verbose_name='Файл ответа'
    )
    
    # Статус и проверка
    status = models.CharField(
        max_length=20,
        choices=STATUS_CHOICES,
        default='pending',
        verbose_name='Статус',
        db_index=True
    )
    
    # Оценка
    score = models.IntegerField(
        null=True,
        blank=True,
        validators=[MinValueValidator(0), MaxValueValidator(100)],
        verbose_name='Оценка',
        help_text='Оценка от 0 до 100'
    )
    
    # Отзыв ментора
    feedback = models.TextField(
        blank=True,
        verbose_name='Отзыв ментора'
    )
    
    checked_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='checked_lesson_homework_submissions',
        null=True,
        blank=True,
        limit_choices_to={'role': 'mentor'},
        verbose_name='Проверил'
    )
    
    checked_at = models.DateTimeField(
        null=True,
        blank=True,
        verbose_name='Дата проверки'
    )
    
    # Временные метки
    submitted_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата отправки'
    )
    
    updated_at = models.DateTimeField(
        auto_now=True,
        verbose_name='Дата обновления'
    )
    
    class Meta:
        db_table = 'lesson_homework_submissions'
        verbose_name = 'Ответ на ДЗ по уроку'
        verbose_name_plural = 'Ответы на ДЗ по урокам'
        ordering = ['-submitted_at']
        indexes = [
            models.Index(fields=['lesson', 'student']),
            models.Index(fields=['student', 'status']),
            models.Index(fields=['status', 'submitted_at']),
        ]
        constraints = [
            models.UniqueConstraint(
                fields=['lesson', 'student'],
                name='unique_lesson_student_submission'
            ),
        ]
    
    def __str__(self):
        return f"{self.student.get_full_name()} - {self.lesson.title} ({self.get_status_display()})"
    
    def grade(self, score, feedback, checked_by):
        """Выставить оценку."""
        self.score = score
        self.feedback = feedback
        self.checked_by = checked_by
        self.checked_at = timezone.now()
        self.status = 'graded'
        self.save()
    
    def return_for_revision(self, feedback):
        """Вернуть на доработку."""
        self.feedback = feedback
        self.status = 'returned'
        self.save()
