"""
Park media serializers for ThrillWiki API v1.

This module contains serializers for park-specific media functionality.
Enhanced from rogue implementation to maintain full feature parity.
"""

from drf_spectacular.utils import (
    OpenApiExample,
    extend_schema_field,
    extend_schema_serializer,
)
from rest_framework import serializers

from apps.parks.models import Park, ParkPhoto


@extend_schema_serializer(
    examples=[
        OpenApiExample(
            name="Park Photo with Cloudflare Images",
            summary="Complete park photo response",
            description="Example response showing all fields including Cloudflare Images URLs and variants",
            value={
                "id": 456,
                "image": "https://imagedelivery.net/account-hash/def456ghi789/public",
                "image_url": "https://imagedelivery.net/account-hash/def456ghi789/public",
                "image_variants": {
                    "thumbnail": "https://imagedelivery.net/account-hash/def456ghi789/thumbnail",
                    "medium": "https://imagedelivery.net/account-hash/def456ghi789/medium",
                    "large": "https://imagedelivery.net/account-hash/def456ghi789/large",
                    "public": "https://imagedelivery.net/account-hash/def456ghi789/public",
                },
                "caption": "Beautiful park entrance",
                "alt_text": "Main entrance gate with decorative archway",
                "is_primary": True,
                "is_approved": True,
                "created_at": "2023-01-01T12:00:00Z",
                "updated_at": "2023-01-01T12:00:00Z",
                "date_taken": "2023-01-01T11:00:00Z",
                "uploaded_by_username": "parkfan456",
                "file_size": 1536000,
                "dimensions": [1600, 900],
                "park_slug": "cedar-point",
                "park_name": "Cedar Point",
            },
        )
    ]
)
class ParkPhotoOutputSerializer(serializers.ModelSerializer):
    """Enhanced output serializer for park photos with Cloudflare Images support."""

    uploaded_by_username = serializers.CharField(source="uploaded_by.username", read_only=True)

    file_size = serializers.SerializerMethodField()
    dimensions = serializers.SerializerMethodField()
    image_url = serializers.SerializerMethodField()
    image_variants = serializers.SerializerMethodField()

    @extend_schema_field(serializers.IntegerField(allow_null=True, help_text="File size in bytes"))
    def get_file_size(self, obj):
        """Get file size in bytes."""
        return obj.file_size

    @extend_schema_field(
        serializers.ListField(
            child=serializers.IntegerField(),
            min_length=2,
            max_length=2,
            allow_null=True,
            help_text="Image dimensions as [width, height] in pixels",
        )
    )
    def get_dimensions(self, obj):
        """Get image dimensions as [width, height]."""
        return obj.dimensions

    @extend_schema_field(serializers.URLField(help_text="Full URL to the Cloudflare Images asset", allow_null=True))
    def get_image_url(self, obj):
        """Get the full Cloudflare Images URL."""
        if obj.image:
            return obj.image.public_url
        return None

    @extend_schema_field(
        serializers.DictField(
            child=serializers.URLField(),
            help_text="Available Cloudflare Images variants with their URLs",
        )
    )
    def get_image_variants(self, obj):
        """Get available image variants from Cloudflare Images."""
        if not obj.image:
            return {}

        # Common variants for park photos
        variants = {
            "thumbnail": f"{obj.image.public_url}/thumbnail",
            "medium": f"{obj.image.public_url}/medium",
            "large": f"{obj.image.public_url}/large",
            "public": f"{obj.image.public_url}/public",
        }
        return variants

    park_slug = serializers.CharField(source="park.slug", read_only=True)
    park_name = serializers.CharField(source="park.name", read_only=True)

    class Meta:
        model = ParkPhoto
        fields = [
            "id",
            "image",
            "image_url",
            "image_variants",
            "caption",
            "photographer",
            "alt_text",
            "is_primary",
            "is_approved",
            "created_at",
            "updated_at",
            "date_taken",
            "uploaded_by_username",
            "file_size",
            "dimensions",
            "park_slug",
            "park_name",
        ]
        read_only_fields = [
            "id",
            "image_url",
            "image_variants",
            "created_at",
            "updated_at",
            "uploaded_by_username",
            "file_size",
            "dimensions",
            "park_slug",
            "park_name",
        ]


class ParkPhotoCreateInputSerializer(serializers.ModelSerializer):
    """Input serializer for creating park photos."""

    class Meta:
        model = ParkPhoto
        fields = [
            "image",
            "caption",
            "photographer",
            "alt_text",
            "is_primary",
        ]


class ParkPhotoUpdateInputSerializer(serializers.ModelSerializer):
    """Input serializer for updating park photos."""

    class Meta:
        model = ParkPhoto
        fields = [
            "caption",
            "photographer",
            "alt_text",
            "is_primary",
        ]


class ParkPhotoListOutputSerializer(serializers.ModelSerializer):
    """Optimized output serializer for park photo lists."""

    uploaded_by_username = serializers.CharField(source="uploaded_by.username", read_only=True)

    class Meta:
        model = ParkPhoto
        fields = [
            "id",
            "image",
            "caption",
            "is_primary",
            "is_approved",
            "created_at",
            "uploaded_by_username",
        ]
        read_only_fields = fields


class ParkPhotoApprovalInputSerializer(serializers.Serializer):
    """Input serializer for bulk photo approval operations."""

    photo_ids = serializers.ListField(child=serializers.IntegerField(), help_text="List of photo IDs to approve")
    approve = serializers.BooleanField(default=True, help_text="Whether to approve (True) or reject (False) the photos")


class ParkPhotoStatsOutputSerializer(serializers.Serializer):
    """Output serializer for park photo statistics."""

    total_photos = serializers.IntegerField()
    approved_photos = serializers.IntegerField()
    pending_photos = serializers.IntegerField()
    has_primary = serializers.BooleanField()
    recent_uploads = serializers.IntegerField()


# Legacy serializers for backwards compatibility
class ParkPhotoSerializer(serializers.ModelSerializer):
    """Legacy serializer for the ParkPhoto model - maintained for compatibility."""

    class Meta:
        model = ParkPhoto
        fields = (
            "id",
            "image",
            "caption",
            "alt_text",
            "is_primary",
            "uploaded_at",
            "uploaded_by",
        )


class HybridParkSerializer(serializers.ModelSerializer):
    """
    Enhanced serializer for hybrid filtering strategy.
    Includes all filterable fields for client-side filtering.
    """

    # Location fields from related ParkLocation
    city = serializers.SerializerMethodField()
    state = serializers.SerializerMethodField()
    country = serializers.SerializerMethodField()
    continent = serializers.SerializerMethodField()
    latitude = serializers.SerializerMethodField()
    longitude = serializers.SerializerMethodField()

    # Company fields
    operator_name = serializers.CharField(source="operator.name", read_only=True)
    operator_id = serializers.IntegerField(source="operator.id", read_only=True, allow_null=True)
    property_owner_name = serializers.CharField(source="property_owner.name", read_only=True, allow_null=True)

    # Image URLs for display
    banner_image_url = serializers.SerializerMethodField()
    card_image_url = serializers.SerializerMethodField()

    # Computed property
    is_closing = serializers.SerializerMethodField()

    # Computed fields for filtering
    opening_year = serializers.IntegerField(read_only=True)
    search_text = serializers.CharField(read_only=True)

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_city(self, obj):
        """Get city from related location."""
        try:
            return obj.location.city if hasattr(obj, "location") and obj.location else None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_state(self, obj):
        """Get state from related location."""
        try:
            return obj.location.state if hasattr(obj, "location") and obj.location else None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_country(self, obj):
        """Get country from related location."""
        try:
            return obj.location.country if hasattr(obj, "location") and obj.location else None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_continent(self, obj):
        """Get continent from related location."""
        try:
            return obj.location.continent if hasattr(obj, "location") and obj.location else None
        except AttributeError:
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_latitude(self, obj):
        """Get latitude from related location."""
        try:
            if hasattr(obj, "location") and obj.location and obj.location.coordinates:
                return obj.location.coordinates[1]  # PostGIS returns [lon, lat]
            return None
        except (AttributeError, IndexError, TypeError):
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_longitude(self, obj):
        """Get longitude from related location."""
        try:
            if hasattr(obj, "location") and obj.location and obj.location.coordinates:
                return obj.location.coordinates[0]  # PostGIS returns [lon, lat]
            return None
        except (AttributeError, IndexError, TypeError):
            return None

    @extend_schema_field(serializers.URLField(allow_null=True))
    def get_banner_image_url(self, obj):
        """Get banner image URL."""
        if obj.banner_image and obj.banner_image.image:
            return obj.banner_image.image.public_url
        return None

    @extend_schema_field(serializers.URLField(allow_null=True))
    def get_card_image_url(self, obj):
        """Get card image URL."""
        if obj.card_image and obj.card_image.image:
            return obj.card_image.image.public_url
        return None

    @extend_schema_field(serializers.BooleanField())
    def get_is_closing(self, obj):
        """Check if park has an announced closing date in the future."""
        return obj.is_closing

    class Meta:
        model = Park
        fields = [
            # Basic park info
            "id",
            "name",
            "slug",
            "description",
            "status",
            "park_type",
            # Dates and computed fields
            "opening_date",
            "opening_date_precision",
            "closing_date",
            "closing_date_precision",
            "is_closing",
            "opening_year",
            "operating_season",
            # Location fields
            "city",
            "state",
            "country",
            "continent",
            "latitude",
            "longitude",
            # Company relationships
            "operator_name",
            "operator_id",
            "property_owner_name",
            # Statistics
            "size_acres",
            "average_rating",
            "ride_count",
            "coaster_count",
            # Contact info
            "phone",
            "email",
            "timezone",
            # Images
            "banner_image_url",
            "card_image_url",
            # URLs
            "website",
            "url",
            # Computed fields for filtering
            "search_text",
            # Metadata
            "created_at",
            "updated_at",
        ]
        read_only_fields = fields


class ParkSerializer(serializers.ModelSerializer):
    """Serializer for the Park model."""

    class Meta:
        model = Park
        fields = (
            "id",
            "name",
            "slug",
            "country",
            "continent",
            "latitude",
            "longitude",
            "website",
            "status",
        )
