from rest_framework import serializers
from .models import DesignSettings


class DesignSettingsSerializer(serializers.ModelSerializer):
    """
    Сериализатор для настроек дизайна пользователя
    """
    background_image_url = serializers.SerializerMethodField()
    
    class Meta:
        model = DesignSettings
        fields = [
            'id',
            'theme_color',
            'background_image',
            'background_image_url',
            'dashboard_layout',
            'groups_default_expanded',
            'show_group_icons',
            'show_link_icons',
            'dashboard_background_color',
            'font_family',
            'custom_css',
            'header_text_color',
            'group_text_color',
            'link_text_color',
            'cover_overlay_enabled',
            'cover_overlay_color',
            'cover_overlay_opacity',
            'updated_at'
        ]
        read_only_fields = ['id', 'updated_at', 'background_image_url']
        # Делаем background_image необязательным
        extra_kwargs = {
            'background_image': {'required': False}
        }

    def get_background_image_url(self, obj):
        """
        Возвращает полный URL фонового изображения
        """
        if obj.background_image:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.background_image.url)
            return obj.background_image.url
        return None

    def update(self, instance, validated_data):
        """
        Переопределяем метод update для обработки случая, когда background_image не передается
        """
        # Специально обрабатываем background_image
        background_image = validated_data.pop('background_image', None)
        
        # Обновляем остальные поля
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        
        # Обновляем background_image только если передан новый файл
        if background_image is not None:
            instance.background_image = background_image
        
        instance.save()
        return instance

    def validate_background_image(self, value):
        """
        Валидация загружаемого изображения
        """
        if value:
            # Проверяем размер файла (максимум 10MB)
            if value.size > 10 * 1024 * 1024:
                raise serializers.ValidationError('Размер файла не должен превышать 10MB')
            
            # Проверяем тип файла
            if not value.content_type.startswith('image/'):
                raise serializers.ValidationError('Файл должен быть изображением')
                
            # Допустимые форматы
            allowed_types = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']
            if value.content_type not in allowed_types:
                raise serializers.ValidationError('Поддерживаются только форматы: JPEG, PNG, GIF, WebP')
        
        return value

    def validate_theme_color(self, value):
        """
        Валидация цвета темы (должен быть в формате hex)
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_dashboard_background_color(self, value):
        """
        Валидация цвета фона дашборда
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_dashboard_layout(self, value):
        """
        Валидация типа макета дашборда
        """
        valid_layouts = ['sidebar', 'grid', 'list', 'cards', 'compact', 'masonry', 'timeline', 'magazine']
        if value not in valid_layouts:
            raise serializers.ValidationError(f'Макет должен быть одним из: {", ".join(valid_layouts)}')
        return value

    def validate_font_family(self, value):
        """
        Валидация шрифта
        """
        if len(value) > 100:
            raise serializers.ValidationError('Название шрифта слишком длинное')
        return value

    def validate_custom_css(self, value):
        """
        Базовая валидация пользовательского CSS
        """
        if len(value) > 10000:  # Ограничение на размер CSS
            raise serializers.ValidationError('CSS код слишком длинный (максимум 10000 символов)')
        
        # Простая проверка на потенциально опасные директивы
        dangerous_patterns = ['@import', 'javascript:', 'expression(']
        for pattern in dangerous_patterns:
            if pattern in value.lower():
                raise serializers.ValidationError(f'Обнаружена потенциально опасная директива: {pattern}')
        
        return value

    def validate_header_text_color(self, value):
        """
        Валидация цвета заголовков
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_group_text_color(self, value):
        """
        Валидация цвета названий групп
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_link_text_color(self, value):
        """
        Валидация цвета названий ссылок
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_cover_overlay_color(self, value):
        """
        Валидация цвета перекрытия обложки
        """
        if not value.startswith('#') or len(value) != 7:
            raise serializers.ValidationError('Цвет должен быть в формате #RRGGBB')
        try:
            int(value[1:], 16)
        except ValueError:
            raise serializers.ValidationError('Некорректный hex цвет')
        return value

    def validate_cover_overlay_opacity(self, value):
        """
        Валидация прозрачности перекрытия обложки
        """
        if not 0.0 <= value <= 1.0:
            raise serializers.ValidationError('Прозрачность должна быть между 0.0 и 1.0')
        return value


class PublicDesignSettingsSerializer(serializers.ModelSerializer):
    """
    Публичный сериализатор для настроек дизайна (только для отображения)
    """
    background_image_url = serializers.SerializerMethodField()
    
    class Meta:
        model = DesignSettings
        fields = [
            'theme_color',
            'background_image_url',
            'font_family',
            'custom_css'
        ]

    def get_background_image_url(self, obj):
        """
        Возвращает полный URL фонового изображения
        """
        if obj.background_image:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.background_image.url)
            return obj.background_image.url
        return None