from rest_framework import serializers
from .models import URL, URLClick, QRCode, ImageToolUsage, FileConversion, ScribdScrape


class URLSerializer(serializers.ModelSerializer):
    is_expired = serializers.SerializerMethodField()
    created_by_email = serializers.EmailField(source='created_by.email', read_only=True)

    class Meta:
        model = URL
        fields = [
            'id', 'original_url', 'short_code', 'title', 'clicks',
            'last_clicked_at', 'expires_at', 'is_expired',
            'created_by', 'created_by_email', 'created_at', 'updated_at'
        ]
        read_only_fields = ['id', 'short_code', 'clicks', 'last_clicked_at', 'created_at', 'updated_at']

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


class URLCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = URL
        fields = ['id', 'original_url', 'title', 'expires_at']
        read_only_fields = ['id']

    def validate_original_url(self, value):
        # Redirect target must be a web URL — block javascript:/data:/etc. as a
        # defense against the short link being used as a scheme-smuggling redirect.
        from urllib.parse import urlparse
        if urlparse(value).scheme.lower() not in ("http", "https"):
            raise serializers.ValidationError("Only http(s) URLs are allowed.")
        return value


class URLClickSerializer(serializers.ModelSerializer):
    class Meta:
        model = URLClick
        fields = ['id', 'url', 'clicked_at', 'ip_address', 'user_agent', 'referer']
        read_only_fields = ['id', 'clicked_at']


class QRCodeSerializer(serializers.ModelSerializer):
    created_by_email = serializers.EmailField(source='created_by.email', read_only=True)
    download_url = serializers.SerializerMethodField()

    class Meta:
        model = QRCode
        fields = [
            'id', 'content', 'short_code', 'title', 'size',
            'format', 'downloads', 'download_url',
            'created_by', 'created_by_email', 'created_at'
        ]
        read_only_fields = ['id', 'short_code', 'downloads', 'created_at']

    def get_download_url(self, obj):
        request = self.context.get('request')
        if request:
            return request.build_absolute_uri(f'/api/tools/qr-codes/{obj.short_code}/download/')
        return None


class QRCodeCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = QRCode
        fields = ['id', 'content', 'title', 'size', 'format']
        read_only_fields = ['id']


class ImageToolUsageSerializer(serializers.ModelSerializer):
    created_by_email = serializers.EmailField(source='created_by.email', read_only=True)

    class Meta:
        model = ImageToolUsage
        fields = [
            'id', 'tool_name', 'original_filename', 'result_filename',
            'original_size', 'result_size', 'compression_ratio',
            'created_by', 'created_by_email', 'created_at'
        ]
        read_only_fields = ['id', 'created_at']


class ImageToolUsageCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = ImageToolUsage
        fields = [
            'id', 'tool_name', 'original_filename', 'result_filename',
            'original_size', 'result_size', 'compression_ratio'
        ]
        read_only_fields = ['id']


class FileConversionSerializer(serializers.ModelSerializer):
    created_by_email = serializers.EmailField(source='created_by.email', read_only=True)

    class Meta:
        model = FileConversion
        fields = [
            'id', 'from_format', 'to_format', 'original_filename',
            'result_filename', 'original_size', 'result_size',
            'created_by', 'created_by_email', 'created_at'
        ]
        read_only_fields = ['id', 'created_at']


class FileConversionCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = FileConversion
        fields = [
            'id', 'from_format', 'to_format', 'original_filename',
            'result_filename', 'original_size', 'result_size'
        ]
        read_only_fields = ['id']


class ScribdScrapeSerializer(serializers.ModelSerializer):
    created_by_email = serializers.EmailField(source='created_by.email', read_only=True)

    class Meta:
        model = ScribdScrape
        fields = [
            'id', 'scribd_url', 'scribd_doc_id', 'title', 'status',
            'output_format', 'file_size', 'page_count',
            'error_message', 'strategy_used',
            'created_by', 'created_by_email', 'created_at', 'updated_at'
        ]
        read_only_fields = [
            'id', 'scribd_doc_id', 'title', 'status',
            'file_size', 'page_count', 'error_message', 'strategy_used',
            'created_at', 'updated_at'
        ]


class ScribdScrapeCreateSerializer(serializers.Serializer):
    scribd_url = serializers.URLField(required=True)
    output_format = serializers.ChoiceField(choices=['pdf', 'txt'], default='pdf')

    def validate_scribd_url(self, value):
        from .scribd import extract_doc_id
        if not extract_doc_id(value):
            raise serializers.ValidationError("Invalid Scribd URL — could not extract document ID.")
        return value
