"""
Сериализаторы для учебных материалов.
"""
from rest_framework import serializers
from django.db import models
from .models import Material, MaterialFolder, MaterialTag, MaterialAccess, StorageQuota
from apps.users.serializers import UserSerializer


class MaterialTagSerializer(serializers.ModelSerializer):
    """Сериализатор тега."""
    
    class Meta:
        model = MaterialTag
        fields = [
            'id',
            'name',
            'slug',
            'color',
            'materials_count'
        ]
        read_only_fields = ['materials_count']


class MaterialFolderSerializer(serializers.ModelSerializer):
    """Сериализатор папки."""
    
    owner = UserSerializer(read_only=True)
    path = serializers.SerializerMethodField()
    
    class Meta:
        model = MaterialFolder
        fields = [
            'id',
            'name',
            'description',
            'owner',
            'parent',
            'path',
            'is_public',
            'materials_count',
            'created_at',
            'updated_at'
        ]
        read_only_fields = ['owner', 'materials_count', 'created_at', 'updated_at']
    
    def get_path(self, obj):
        """Получить путь папки."""
        return obj.get_path()


class MaterialSerializer(serializers.ModelSerializer):
    """Сериализатор материала."""
    
    owner = UserSerializer(read_only=True)
    folder = MaterialFolderSerializer(read_only=True)
    tags = MaterialTagSerializer(many=True, read_only=True)
    shared_with = UserSerializer(many=True, read_only=True)
    
    class Meta:
        model = Material
        fields = [
            'id',
            'title',
            'description',
            'file',
            'file_name',
            'file_size',
            'file_type',
            'url',
            'material_type',
            'owner',
            'folder',
            'tags',
            'lesson',
            'homework',
            'access_type',
            'allow_download',
            'is_featured',
            'shared_with',
            'views_count',
            'downloads_count',
            'created_at',
            'updated_at'
        ]
        read_only_fields = [
            'owner',
            'file_name',
            'file_size',
            'file_type',
            'views_count',
            'downloads_count',
            'created_at',
            'updated_at'
        ]


class MaterialListSerializer(serializers.ModelSerializer):
    """Сериализатор списка материалов (упрощенный)."""
    
    owner = UserSerializer(read_only=True)
    tags = MaterialTagSerializer(many=True, read_only=True)
    file_url = serializers.SerializerMethodField()
    
    class Meta:
        model = Material
        fields = [
            'id',
            'title',
            'description',
            'file',
            'file_url',
            'file_name',
            'file_size',
            'file_type',
            'url',
            'material_type',
            'owner',
            'folder',
            'tags',
            'access_type',
            'is_featured',
            'views_count',
            'created_at'
        ]
    
    def get_file_url(self, obj):
        """Полный URL файла для превью (изображения, видео)."""
        if obj.file:
            request = self.context.get('request')
            if request:
                return request.build_absolute_uri(obj.file.url)
            return obj.file.url
        return None


class MaterialCreateSerializer(serializers.ModelSerializer):
    """Сериализатор создания материала."""
    
    folder_id = serializers.IntegerField(required=False, allow_null=True)
    tag_ids = serializers.ListField(
        child=serializers.IntegerField(),
        required=False,
        allow_empty=True
    )
    
    class Meta:
        model = Material
        fields = [
            'title',
            'description',
            'file',
            'url',
            'material_type',
            'folder_id',
            'tag_ids',
            'lesson',
            'homework',
            'access_type',
            'allow_download',
            'is_featured'
        ]
    
    def validate(self, attrs):
        """Валидация."""
        from .services import StorageService
        
        # Проверяем что указан file или url
        if not attrs.get('file') and not attrs.get('url'):
            raise serializers.ValidationError({
                'file': 'Необходимо указать файл или ссылку'
            })
        
        # Проверяем квоту если загружается файл
        if attrs.get('file'):
            user = self.context['request'].user
            file_size = attrs['file'].size
            
            # Используем сервис для проверки лимита
            can_upload, error_message, warning_message = StorageService.check_storage_limit(user, file_size)
            
            if not can_upload:
                raise serializers.ValidationError({
                    'file': error_message
                })
            
            # Сохраняем предупреждение в контексте для использования в create
            if warning_message:
                self.context['storage_warning'] = warning_message
        
        return attrs
    
    def create(self, validated_data):
        """Создание материала."""
        folder_id = validated_data.pop('folder_id', None)
        tag_ids = validated_data.pop('tag_ids', [])
        user = self.context['request'].user
        
        # Получаем информацию о файле
        file = validated_data.get('file')
        if file:
            validated_data['file_name'] = file.name
            validated_data['file_size'] = file.size
            validated_data['file_type'] = file.content_type
        
        # Создаем материал с owner (owner будет переопределен в perform_create, но нужен для создания)
        material = Material.objects.create(
            owner=user,
            folder_id=folder_id,
            **validated_data
        )
        
        # Добавляем теги
        if tag_ids:
            tags = MaterialTag.objects.filter(id__in=tag_ids)
            material.tags.set(tags)
        
        # Обновляем квоту если загружен файл
        if file:
            from .services import StorageService
            StorageService.add_file_usage(user, file.size)
        
        return material


class StorageQuotaSerializer(serializers.ModelSerializer):
    """Сериализатор квоты хранилища."""
    
    user = UserSerializer(read_only=True)
    used_percentage = serializers.SerializerMethodField()
    available_space = serializers.SerializerMethodField()
    total_quota_mb = serializers.SerializerMethodField()
    used_space_mb = serializers.SerializerMethodField()
    available_space_mb = serializers.SerializerMethodField()
    is_warning = serializers.SerializerMethodField()
    is_critical = serializers.SerializerMethodField()
    
    class Meta:
        model = StorageQuota
        fields = [
            'id',
            'user',
            'total_quota',
            'used_space',
            'used_percentage',
            'available_space',
            'total_quota_mb',
            'used_space_mb',
            'available_space_mb',
            'is_warning',
            'is_critical',
            'created_at',
            'updated_at'
        ]
        read_only_fields = ['user', 'used_space', 'created_at', 'updated_at']
    
    def get_used_percentage(self, obj):
        """Процент использования."""
        return round(obj.get_used_percentage(), 2)
    
    def get_available_space(self, obj):
        """Доступное пространство."""
        return obj.get_available_space()
    
    def get_total_quota_mb(self, obj):
        """Лимит в МБ."""
        return round(obj.total_quota / (1024 * 1024), 2)
    
    def get_used_space_mb(self, obj):
        """Использовано в МБ."""
        return round(obj.used_space / (1024 * 1024), 2)
    
    def get_available_space_mb(self, obj):
        """Доступно в МБ."""
        return round(obj.get_available_space() / (1024 * 1024), 2)
    
    def get_is_warning(self, obj):
        """Предупреждение (80% и выше)."""
        return obj.get_used_percentage() >= 80
    
    def get_is_critical(self, obj):
        """Критическое состояние (90% и выше)."""
        return obj.get_used_percentage() >= 90


class MaterialAccessSerializer(serializers.ModelSerializer):
    """Сериализатор лога доступа."""
    
    user = UserSerializer(read_only=True)
    material = MaterialListSerializer(read_only=True)
    
    class Meta:
        model = MaterialAccess
        fields = [
            'id',
            'material',
            'user',
            'action',
            'ip_address',
            'created_at'
        ]
        read_only_fields = ['user', 'created_at']
