"""
Сериализаторы для интерактивной доски.
"""
from rest_framework import serializers
from .models import Board, BoardElement, BoardSnapshot
from apps.users.serializers import UserSerializer


class BoardElementSerializer(serializers.ModelSerializer):
    """Сериализатор элемента доски."""
    
    created_by = UserSerializer(read_only=True)
    locked_by = UserSerializer(read_only=True)
    
    class Meta:
        model = BoardElement
        fields = [
            'id',
            'board',
            'element_type',
            'x',
            'y',
            'width',
            'height',
            'rotation',
            'z_index',
            'content',
            'font_size',
            'font_family',
            'font_weight',
            'text_align',
            'text_color',
            'shape_type',
            'fill_color',
            'stroke_color',
            'stroke_width',
            'opacity',
            'image_url',
            'drawing_data',
            'arrow_start_element',
            'arrow_end_element',
            'created_by',
            'locked',
            'locked_by',
            'is_deleted',
            'created_at',
            'updated_at'
        ]
        read_only_fields = [
            'created_by',
            'locked_by',
            'is_deleted',
            'created_at',
            'updated_at'
        ]


class BoardElementCreateSerializer(serializers.ModelSerializer):
    """Сериализатор создания элемента доски."""
    
    board_id = serializers.UUIDField(write_only=True)
    
    class Meta:
        model = BoardElement
        fields = [
            'board_id',
            'element_type',
            'x',
            'y',
            'width',
            'height',
            'rotation',
            'z_index',
            'content',
            'font_size',
            'font_family',
            'font_weight',
            'text_align',
            'text_color',
            'shape_type',
            'fill_color',
            'stroke_color',
            'stroke_width',
            'opacity',
            'image_url',
            'drawing_data',
        ]
    
    def validate_board_id(self, value):
        """Проверка доски."""
        try:
            board = Board.objects.get(board_id=value)
        except Board.DoesNotExist:
            raise serializers.ValidationError('Доска не найдена')
        
        # Проверяем доступ
        user = self.context['request'].user
        if not board.has_access(user):
            raise serializers.ValidationError('У вас нет доступа к этой доске')
        
        return value
    
    def create(self, validated_data):
        """Создание элемента."""
        board_id = validated_data.pop('board_id')
        board = Board.objects.get(board_id=board_id)
        user = self.context['request'].user
        
        element = BoardElement.objects.create(
            board=board,
            created_by=user,
            **validated_data
        )
        
        # Обновляем счетчик элементов
        board.update_elements_count()
        
        # Отмечаем редактирование
        board.mark_edited(user)
        
        return element


class BoardSerializer(serializers.ModelSerializer):
    """Сериализатор доски."""
    
    owner = UserSerializer(read_only=True)
    mentor = UserSerializer(read_only=True)
    student = UserSerializer(read_only=True)
    participants = UserSerializer(many=True, read_only=True)
    last_edited_by = UserSerializer(read_only=True)
    elements = BoardElementSerializer(many=True, read_only=True)
    files_count = serializers.SerializerMethodField()
    snapshot_elements_count = serializers.SerializerMethodField()
    
    class Meta:
        model = Board
        fields = [
            'id',
            'board_id',
            'title',
            'description',
            'owner',
            'mentor',
            'student',
            'access_type',
            'participants',
            'background_color',
            'grid_enabled',
            'width',
            'height',
            'is_active',
            'is_template',
            'views_count',
            'elements_count',
            'files_count',
            'snapshot_elements_count',
            'last_edited_by',
            'last_edited_at',
            'elements',
            'created_at',
            'updated_at'
        ]
        read_only_fields = [
            'board_id',
            'owner',
            'mentor',
            'student',
            'views_count',
            'elements_count',
            'last_edited_by',
            'last_edited_at',
            'created_at',
            'updated_at'
        ]
    
    def get_files_count(self, obj):
        """Получить количество файлов изображений из snapshot."""
        return obj.get_files_count()
    
    def get_snapshot_elements_count(self, obj):
        """Получить количество элементов из snapshot."""
        return obj.get_elements_count_from_snapshot()


class BoardListSerializer(serializers.ModelSerializer):
    """Сериализатор списка досок (упрощенный)."""
    
    owner = UserSerializer(read_only=True)
    mentor = UserSerializer(read_only=True)
    student = UserSerializer(read_only=True)
    last_edited_by = UserSerializer(read_only=True)
    
    class Meta:
        model = Board
        fields = [
            'id',
            'board_id',
            'title',
            'description',
            'owner',
            'mentor',
            'student',
            'access_type',
            'background_color',
            'is_active',
            'is_template',
            'views_count',
            'elements_count',
            'last_edited_by',
            'last_edited_at',
            'created_at'
        ]


class BoardCreateSerializer(serializers.ModelSerializer):
    """Сериализатор создания доски."""
    
    # mentor и student обязательны для доски типа mentor_student
    mentor = serializers.IntegerField(required=False, allow_null=True)
    student = serializers.IntegerField(required=False, allow_null=True)
    participant_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        allow_empty=True
    )
    
    class Meta:
        model = Board
        fields = [
            'title',
            'description',
            'mentor',
            'student',
            'access_type',
            'participant_ids',
            'background_color',
            'grid_enabled',
            'width',
            'height',
            'is_template'
        ]
    
    def validate(self, attrs):
        """Валидация данных доски."""
        # Для доски типа mentor_student требуются mentor и student
        if attrs.get('access_type') == 'mentor_student':
            if not attrs.get('mentor') or not attrs.get('student'):
                raise serializers.ValidationError(
                    'Для доски типа mentor_student требуются поля mentor и student'
                )
        return attrs
    
    def create(self, validated_data):
        """Создание доски."""
        from apps.users.models import User
        
        mentor_id = validated_data.pop('mentor', None)
        student_id = validated_data.pop('student', None)
        participant_ids = validated_data.pop('participant_ids', [])
        user = self.context['request'].user
        
        # Создаем доску
        board_data = {
            'owner': user,
            **validated_data
        }
        
        # Добавляем ментора и студента
        if mentor_id:
            board_data['mentor_id'] = mentor_id
        if student_id:
            board_data['student_id'] = student_id
        
        board = Board.objects.create(**board_data)
        
        # Добавляем участников
        if participant_ids:
            participants = User.objects.filter(id__in=participant_ids)
            board.participants.set(participants)
        
        # Если указаны ментор и студент, добавляем их как участников
        if mentor_id or student_id:
            if mentor_id:
                board.participants.add(User.objects.get(id=mentor_id))
            if student_id:
                board.participants.add(User.objects.get(id=student_id))
        
        return board


class BoardSnapshotSerializer(serializers.ModelSerializer):
    """Сериализатор снимка доски."""
    
    created_by = UserSerializer(read_only=True)
    
    class Meta:
        model = BoardSnapshot
        fields = [
            'id',
            'board',
            'snapshot_data',
            'created_by',
            'description',
            'created_at'
        ]
        read_only_fields = [
            'created_by',
            'created_at'
        ]


class BoardSnapshotCreateSerializer(serializers.ModelSerializer):
    """Сериализатор создания снимка доски."""
    
    board_id = serializers.UUIDField(write_only=True)
    
    class Meta:
        model = BoardSnapshot
        fields = [
            'board_id',
            'description'
        ]
    
    def validate_board_id(self, value):
        """Проверка доски."""
        try:
            board = Board.objects.get(board_id=value)
        except Board.DoesNotExist:
            raise serializers.ValidationError('Доска не найдена')
        
        # Проверяем доступ
        user = self.context['request'].user
        if not board.has_access(user):
            raise serializers.ValidationError('У вас нет доступа к этой доске')
        
        return value
    
    def create(self, validated_data):
        """Создание снимка."""
        board_id = validated_data.pop('board_id')
        board = Board.objects.get(board_id=board_id)
        user = self.context['request'].user
        
        # Собираем данные всех элементов
        elements = board.elements.filter(is_deleted=False)
        elements_data = BoardElementSerializer(elements, many=True).data
        
        snapshot_data = {
            'board': BoardSerializer(board).data,
            'elements': elements_data,
            'timestamp': timezone.now().isoformat()
        }
        
        snapshot = BoardSnapshot.objects.create(
            board=board,
            created_by=user,
            snapshot_data=snapshot_data,
            **validated_data
        )
        
        return snapshot
