import os

from django.utils.text import slugify
from rest_framework import serializers

from users.models import User
from .models import (
    UploadedImage,
    Category,
    Post,
    Comment,
    Page,
    Tag,
)

# Serialized do tagów
class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tag
        fields = ['id', 'name', 'slug']
        read_only_fields = ['id']

# Serialized do kategorii
class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name', 'slug', 'description', 'parent_category', 'created_at']
        read_only_fields = ['id', 'created_at']

# Serialized do użytkowników
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ['id', 'username', 'first_name', 'last_name']
        read_only_fields = ['id']

# Serialized do komentarzy
class CommentSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)

    class Meta:
        model = Comment
        fields = ['id', 'content', 'author', 'post', 'page', 'approved', 'created_at']
        read_only_fields = ['id', 'created_at', 'author']

# Serialized do postów
class PostSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    category = CategorySerializer(read_only=True)
    category_id = serializers.PrimaryKeyRelatedField(
        queryset=Category.objects.all(),
        source='category',
        write_only=True
    )
    comments = CommentSerializer(many=True, read_only=True)
    tags = TagSerializer(many=True, read_only=True)
    tag_ids = serializers.PrimaryKeyRelatedField(
        queryset=Tag.objects.all(),
        source='tags',
        many=True,
        write_only=True,
        required=False
    )
    slug = serializers.SlugField(required=True)

    meta_title = serializers.CharField(required=False, allow_blank=True)
    meta_description = serializers.CharField(required=False, allow_blank=True)
    meta_image = serializers.CharField(required=False, allow_null=True)

    class Meta:
        model = Post
        fields = [
            'id', 'title', 'content', 'status', 'author',
            'category', 'category_id', 'comments',
            'created_at', 'updated_at', 'tags', 'tag_ids', 'slug',
            'meta_title', 'meta_description', 'meta_image',]
        read_only_fields = ['id', 'created_at', 'updated_at', 'author', 'slug']
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }

    def create(self, validated_data):
        if not validated_data.get('slug'):
            validated_data['slug'] = slugify(validated_data.get('title', ''))
        return super().create(validated_data)

    def update(self, instance, validated_data):
        if not validated_data.get('slug') and validated_data.get('title'):
            validated_data['slug'] = slugify(validated_data['title'])
        return super().update(instance, validated_data)
    
# Serialized do stron
class PageSerializer(serializers.ModelSerializer):
    author = UserSerializer(read_only=True)
    category = CategorySerializer(read_only=True)
    category_id = serializers.PrimaryKeyRelatedField(
        queryset=Category.objects.all(),
        source='category',
        write_only=True
    )
    comments = CommentSerializer(many=True, read_only=True)
    slug = serializers.SlugField(required=True)

    meta_title = serializers.CharField(required=False, allow_blank=True)
    meta_description = serializers.CharField(required=False, allow_blank=True)
    meta_image = serializers.ImageField(required=False, allow_null=True)

    class Meta:
        model = Page
        fields = [
            'id', 'title', 'content', 'status', 'author',
            'category', 'category_id', 'comments',
            'created_at', 'updated_at', 'slug',
            'meta_title', 'meta_description', 'meta_image']
        read_only_fields = ['id', 'created_at', 'updated_at', 'author', 'slug']
        lookup_field = 'slug'
        extra_kwargs = {
            'url': {'lookup_field': 'slug'}
        }

# Serialized do przesłanych obrazów
class UploadedImageSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField()
    file_size_display = serializers.SerializerMethodField()
    image = serializers.ImageField(required=True)

    class Meta:
        model = UploadedImage
        fields = [
            'id',
            'title',
            'image',
            'url',
            'uploaded_at',
            'file_size',
            'file_size_display',
            'category',
            'description',
        ]
        read_only_fields = ['file_size', 'uploaded_at', 'url']

    def get_url(self, obj):
        request = self.context.get('request')
        if obj.image and hasattr(obj.image, 'url'):
            return request.build_absolute_uri(obj.image.url) if request else obj.image.url
        return None
    
    def get_file_size_display(self, obj):
        print(f"Rozmiar pliku: {obj.file_size}")
        size = obj.file_size
        if size is None:
            return "0 B"  # albo return None

        for unit in ['B', 'KB', 'MB', 'GB']:
            if size < 1024.0:
                return f"{size:.1f} {unit}"
            size /= 1024.0
        return f"{size:.1f} TB"

    def validate_image(self, value):
        if not value:
            raise serializers.ValidationError("Image file is required.")
        return value
    url = serializers.SerializerMethodField()
    file_size_display = serializers.SerializerMethodField()
    image = serializers.ImageField(required=True)

    def get_url(self, obj):
        request = self.context.get('request')
        if obj.image and hasattr(obj.image, 'url'):
            return request.build_absolute_uri(obj.image.url) if request else obj.image.url
        return None

    def get_file_size_display(self, obj):
        """Convert bytes to human readable format"""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if obj.file_size < 1024.0:
                return f"{obj.file_size:.1f} {unit}"
            obj.file_size /= 1024.0
        return f"{obj.file_size:.1f} TB"

    def validate_image(self, value):
        if not value:
            raise serializers.ValidationError("Image file is required.")
        return value

    def validate_category(self, value):
        if not Category.objects.filter(id=value.id if isinstance(value, Category) else value).exists():
            raise serializers.ValidationError("Wybrana kategoria nie istnieje.")
        return value