from rest_framework import serializers
from .models import Link, Page, Post, ImageCollection, Image, Tag, FileUpload


class LinkSerializer(serializers.ModelSerializer):
    tags = serializers.SerializerMethodField()

    class Meta:
        model = Link
        fields = ['id', 'alias', 'original_url', 'description', 'link_type',
                  'click_count', 'tags', 'created_at', 'updated_at']
        read_only_fields = ['id', 'click_count', 'created_at', 'updated_at']

    def get_tags(self, obj):
        return [{'id': tag.id, 'name': tag.name, 'slug': tag.slug} for tag in obj.tags.all()]

class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = Page
        fields = ['id', 'url', 'title', 'summary', 'content', 'screenshot_path',
                 'process_status', 'created_at', 'updated_at']
        read_only_fields = ['id', 'screenshot_path', 'process_status',
                          'created_at', 'updated_at']

class PostSerializer(serializers.ModelSerializer):
    tags = serializers.ListField(child=serializers.CharField(), required=False, write_only=True, help_text="List of tag slugs")
    tag_details = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Post
        fields = ['id', 'title', 'summary', 'content', 'is_public', 'tags', 'tag_details', 'created_at', 'updated_at']
        read_only_fields = ['id', 'created_at', 'updated_at']
        extra_kwargs = {
            'title': {'required': True},
            'content': {'required': True},
            'summary': {'required': False}
        }

    def get_tag_details(self, obj):
        return [{'id': tag.id, 'name': tag.name, 'slug': tag.slug} for tag in obj.tags.all()]

    def create(self, validated_data):
        tag_slugs = validated_data.pop('tags', [])
        post = Post.objects.create(**validated_data)

        for tag_slug in tag_slugs:
            try:
                tag = Tag.objects.get(slug=tag_slug)
            except Tag.DoesNotExist:
                # If tag doesn't exist, create it with the slug as both name and slug
                tag = Tag.objects.create(name=tag_slug, slug=tag_slug)
            post.tags.add(tag)

        return post

    def update(self, instance, validated_data):
        tag_slugs = validated_data.pop('tags', None)
        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        if tag_slugs is not None:
            instance.tags.clear()
            for tag_slug in tag_slugs:
                try:
                    tag = Tag.objects.get(slug=tag_slug)
                except Tag.DoesNotExist:
                    # If tag doesn't exist, create it with the slug as both name and slug
                    tag = Tag.objects.create(name=tag_slug, slug=tag_slug)
                instance.tags.add(tag)

        instance.save()
        return instance

class ImageSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField()

    class Meta:
        model = Image
        fields = ['id', 'collection', 'title', 'description', 'content_type', 'size', 'created_at', 'updated_at', 'url']
        read_only_fields = ['id', 'collection', 'content_type', 'size', 'created_at', 'updated_at']

    def get_url(self, obj):
        return obj.get_url()

class ImageDescriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Image
        fields = ['description']

class ImageCollectionSerializer(serializers.ModelSerializer):
    image_count = serializers.SerializerMethodField()

    class Meta:
        model = ImageCollection
        fields = ['id', 'name', 'description', 'image_count', 'created_at']

    def get_image_count(self, obj):
        return obj.images.count()

class FileUploadSerializer(serializers.ModelSerializer):
    formatted_size = serializers.SerializerMethodField()
    public_url = serializers.SerializerMethodField()
    is_expired = serializers.SerializerMethodField()

    class Meta:
        model = FileUpload
        fields = [
            'id', 'name', 'mime_type', 'size', 'formatted_size',
            'is_public', 'public_token', 'public_url',
            'expires_at', 'is_expired',
            'download_count', 'created_at', 'updated_at',
        ]
        read_only_fields = [
            'id', 'mime_type', 'size', 'formatted_size',
            'public_token', 'public_url', 'is_expired',
            'download_count', 'created_at', 'updated_at',
        ]

    def get_formatted_size(self, obj):
        return obj.formatted_size()

    def get_public_url(self, obj):
        return obj.public_url

    def get_is_expired(self, obj):
        return obj.is_expired
