"""
Модели для интерактивной доски.
"""
from django.db import models
from django.utils import timezone
import uuid


class Board(models.Model):
    """
    Модель интерактивной доски.
    Miro-подобная доска для совместной работы.
    """
    
    ACCESS_CHOICES = [
        ('private', 'Приватная'),
        ('mentor_student', 'Для пары ментор-студент'),
        ('public', 'Публичная'),
    ]
    
    # Уникальный идентификатор
    board_id = models.UUIDField(
        default=uuid.uuid4,
        unique=True,
        editable=False,
        verbose_name='ID доски'
    )
    
    # Основная информация
    title = models.CharField(
        max_length=255,
        verbose_name='Название'
    )
    
    description = models.TextField(
        blank=True,
        verbose_name='Описание'
    )
    
    # Владелец
    owner = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='owned_boards',
        verbose_name='Владелец'
    )
    
    # Связь ментор-студент (для персональной доски)
    mentor = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='mentor_boards',
        null=True,
        blank=True,
        verbose_name='Ментор'
    )
    
    student = models.ForeignKey(
        'users.User',
        on_delete=models.CASCADE,
        related_name='student_boards',
        null=True,
        blank=True,
        verbose_name='Студент'
    )
    
    # Поле lesson удалено - доска привязана к паре mentor-student, а не к уроку
    # Доска доступна и вне занятия
    
    # Доступ
    access_type = models.CharField(
        max_length=20,
        choices=ACCESS_CHOICES,
        default='private',
        verbose_name='Тип доступа',
        db_index=True
    )
    
    # Участники (для приватных досок)
    participants = models.ManyToManyField(
        'users.User',
        related_name='boards',
        blank=True,
        verbose_name='Участники'
    )
    
    # Настройки доски
    background_color = models.CharField(
        max_length=7,
        default='#FFFFFF',
        verbose_name='Цвет фона'
    )
    
    grid_enabled = models.BooleanField(
        default=True,
        verbose_name='Сетка включена'
    )
    
    width = models.IntegerField(
        default=5000,
        verbose_name='Ширина (px)'
    )
    
    height = models.IntegerField(
        default=5000,
        verbose_name='Высота (px)'
    )
    
    # Статус
    is_active = models.BooleanField(
        default=True,
        verbose_name='Активна',
        db_index=True
    )
    
    is_template = models.BooleanField(
        default=False,
        verbose_name='Шаблон'
    )
    
    # Тип доски
    BOARD_TYPE_CHOICES = [
        ('tldraw', 'Tldraw'),
        ('whiteboard', 'Whiteboard'),
        ('spacedeck', 'Spacedeck'),
    ]
    
    board_type = models.CharField(
        max_length=20,
        choices=BOARD_TYPE_CHOICES,
        default='whiteboard',
        verbose_name='Тип доски',
        db_index=True
    )
    
    # Tldraw данные
    tldraw_snapshot = models.JSONField(
        default=dict,
        blank=True,
        verbose_name='Tldraw состояние',
        help_text='Полное состояние Tldraw доски'
    )
    
    # Spacedeck данные
    spacedeck_id = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        verbose_name='Spacedeck Space ID'
    )
    
    spacedeck_edit_hash = models.CharField(
        max_length=255,
        blank=True,
        null=True,
        unique=True,
        verbose_name='Spacedeck Edit Hash'
    )
    
    # Статистика
    views_count = models.IntegerField(
        default=0,
        verbose_name='Количество просмотров'
    )
    
    elements_count = models.IntegerField(
        default=0,
        verbose_name='Количество элементов'
    )
    
    last_edited_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='last_edited_boards',
        null=True,
        blank=True,
        verbose_name='Последний редактор'
    )
    
    last_edited_at = models.DateTimeField(
        null=True,
        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 = 'boards'
        verbose_name = 'Доска'
        verbose_name_plural = 'Доски'
        ordering = ['-last_edited_at', '-created_at']
        unique_together = [('mentor', 'student')]
        indexes = [
            models.Index(fields=['board_id']),
            models.Index(fields=['owner', 'is_active']),
            models.Index(fields=['mentor', 'student']),
            models.Index(fields=['access_type', 'is_active']),
        ]
    
    def __str__(self):
        return self.title
    
    def increment_views(self):
        """Увеличить счетчик просмотров."""
        self.views_count += 1
        self.save(update_fields=['views_count'])
    
    def update_elements_count(self):
        """Обновить количество элементов."""
        self.elements_count = self.elements.filter(is_deleted=False).count()
        self.save(update_fields=['elements_count'])
    
    def get_files_count(self):
        """Получить количество файлов изображений из tldraw_snapshot."""
        if not self.tldraw_snapshot or not isinstance(self.tldraw_snapshot, dict):
            return 0
        
        files = self.tldraw_snapshot.get('files', {})
        if not isinstance(files, dict):
            return 0
        
        # Подсчитываем только файлы с dataURL (валидные изображения)
        count = 0
        for file_id, file_data in files.items():
            if isinstance(file_data, dict) and file_data.get('dataURL'):
                count += 1
        
        return count
    
    def get_elements_count_from_snapshot(self):
        """Получить количество элементов из tldraw_snapshot."""
        if not self.tldraw_snapshot or not isinstance(self.tldraw_snapshot, dict):
            return 0
        
        elements = self.tldraw_snapshot.get('elements', [])
        if not isinstance(elements, list):
            return 0
        
        return len(elements)
    
    def mark_edited(self, user):
        """Отметить изменение доски."""
        self.last_edited_by = user
        self.last_edited_at = timezone.now()
        self.save(update_fields=['last_edited_by', 'last_edited_at'])
    
    def has_access(self, user):
        """Проверка доступа пользователя к доске."""
        # Владелец всегда имеет доступ
        if self.owner == user:
            return True
        
        # Публичные доски доступны всем
        if self.access_type == 'public':
            return True
        
        # Участники имеют доступ
        if self.participants.filter(id=user.id).exists():
            return True
        
        # Для досок пары ментор-студент проверяем, что пользователь - ментор или студент
        if self.access_type == 'mentor_student':
            if self.mentor and self.student:
                return user in [self.mentor, self.student]
        
        return False


class BoardElement(models.Model):
    """
    Элемент доски (текст, фигура, изображение, рисунок).
    """
    
    TYPE_CHOICES = [
        ('text', 'Текст'),
        ('shape', 'Фигура'),
        ('image', 'Изображение'),
        ('drawing', 'Рисунок'),
        ('sticky', 'Стикер'),
        ('arrow', 'Стрелка'),
        ('line', 'Линия'),
    ]
    
    SHAPE_CHOICES = [
        ('rectangle', 'Прямоугольник'),
        ('circle', 'Круг'),
        ('triangle', 'Треугольник'),
        ('star', 'Звезда'),
    ]
    
    # Доска
    board = models.ForeignKey(
        Board,
        on_delete=models.CASCADE,
        related_name='elements',
        verbose_name='Доска'
    )
    
    # Тип элемента
    element_type = models.CharField(
        max_length=20,
        choices=TYPE_CHOICES,
        verbose_name='Тип элемента',
        db_index=True
    )
    
    # Позиция и размер
    x = models.FloatField(
        verbose_name='Позиция X'
    )
    
    y = models.FloatField(
        verbose_name='Позиция Y'
    )
    
    width = models.FloatField(
        default=100,
        verbose_name='Ширина'
    )
    
    height = models.FloatField(
        default=100,
        verbose_name='Высота'
    )
    
    rotation = models.FloatField(
        default=0,
        verbose_name='Поворот (градусы)'
    )
    
    z_index = models.IntegerField(
        default=0,
        verbose_name='Z-индекс (слой)'
    )
    
    # Содержимое (для текста)
    content = models.TextField(
        blank=True,
        verbose_name='Содержимое'
    )
    
    # Стиль текста
    font_size = models.IntegerField(
        default=16,
        verbose_name='Размер шрифта'
    )
    
    font_family = models.CharField(
        max_length=100,
        default='Arial',
        verbose_name='Шрифт'
    )
    
    font_weight = models.CharField(
        max_length=20,
        default='normal',
        verbose_name='Жирность'
    )
    
    text_align = models.CharField(
        max_length=20,
        default='left',
        verbose_name='Выравнивание'
    )
    
    text_color = models.CharField(
        max_length=7,
        default='#000000',
        verbose_name='Цвет текста'
    )
    
    # Стиль фигуры
    shape_type = models.CharField(
        max_length=20,
        choices=SHAPE_CHOICES,
        blank=True,
        verbose_name='Тип фигуры'
    )
    
    fill_color = models.CharField(
        max_length=7,
        default='#FFFFFF',
        verbose_name='Цвет заливки'
    )
    
    stroke_color = models.CharField(
        max_length=7,
        default='#000000',
        verbose_name='Цвет границы'
    )
    
    stroke_width = models.FloatField(
        default=1,
        verbose_name='Толщина границы'
    )
    
    opacity = models.FloatField(
        default=1.0,
        verbose_name='Прозрачность (0-1)'
    )
    
    # Для изображений
    image_url = models.URLField(
        blank=True,
        max_length=500,
        verbose_name='URL изображения'
    )
    
    # Для рисунков (SVG path или JSON)
    drawing_data = models.TextField(
        blank=True,
        verbose_name='Данные рисунка'
    )
    
    # Связь со стрелкой
    arrow_start_element = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        related_name='arrow_targets',
        null=True,
        blank=True,
        verbose_name='Начало стрелки'
    )
    
    arrow_end_element = models.ForeignKey(
        'self',
        on_delete=models.SET_NULL,
        related_name='arrow_sources',
        null=True,
        blank=True,
        verbose_name='Конец стрелки'
    )
    
    # Автор
    created_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='board_elements',
        null=True,
        verbose_name='Автор'
    )
    
    # Блокировка редактирования
    locked = models.BooleanField(
        default=False,
        verbose_name='Заблокирован'
    )
    
    locked_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='locked_elements',
        null=True,
        blank=True,
        verbose_name='Заблокировал'
    )
    
    # Удаление (мягкое)
    is_deleted = models.BooleanField(
        default=False,
        verbose_name='Удален',
        db_index=True
    )
    
    deleted_at = models.DateTimeField(
        null=True,
        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 = 'board_elements'
        verbose_name = 'Элемент доски'
        verbose_name_plural = 'Элементы доски'
        ordering = ['z_index', 'created_at']
        indexes = [
            models.Index(fields=['board', 'is_deleted']),
            models.Index(fields=['element_type']),
            models.Index(fields=['z_index']),
        ]
    
    def __str__(self):
        return f"{self.get_element_type_display()} - {self.board.title}"
    
    def soft_delete(self):
        """Мягкое удаление элемента."""
        self.is_deleted = True
        self.deleted_at = timezone.now()
        self.save()
        
        # Обновляем счетчик элементов доски
        self.board.update_elements_count()
    
    def lock(self, user):
        """Заблокировать элемент для редактирования."""
        self.locked = True
        self.locked_by = user
        self.save(update_fields=['locked', 'locked_by'])
    
    def unlock(self):
        """Разблокировать элемент."""
        self.locked = False
        self.locked_by = None
        self.save(update_fields=['locked', 'locked_by'])


class BoardSnapshot(models.Model):
    """
    Снимок доски (для истории изменений).
    """
    
    board = models.ForeignKey(
        Board,
        on_delete=models.CASCADE,
        related_name='snapshots',
        verbose_name='Доска'
    )
    
    # Снимок данных (JSON)
    snapshot_data = models.JSONField(
        verbose_name='Данные снимка'
    )
    
    # Автор изменений
    created_by = models.ForeignKey(
        'users.User',
        on_delete=models.SET_NULL,
        related_name='board_snapshots',
        null=True,
        verbose_name='Автор'
    )
    
    # Описание изменений
    description = models.CharField(
        max_length=255,
        blank=True,
        verbose_name='Описание'
    )
    
    # Временная метка
    created_at = models.DateTimeField(
        auto_now_add=True,
        verbose_name='Дата создания'
    )
    
    class Meta:
        db_table = 'board_snapshots'
        verbose_name = 'Снимок доски'
        verbose_name_plural = 'Снимки досок'
        ordering = ['-created_at']
    
    def __str__(self):
        return f"Снимок {self.board.title} - {self.created_at}"
