"""
Ride media serializers for ThrillWiki API v1.

This module contains serializers for ride-specific media functionality.
"""

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

from apps.rides.models import Ride, RidePhoto


@extend_schema_serializer(
    examples=[
        OpenApiExample(
            name="Ride Photo with Cloudflare Images",
            summary="Complete ride photo response",
            description="Example response showing all fields including Cloudflare Images URLs and variants",
            value={
                "id": 123,
                "image": "https://imagedelivery.net/account-hash/abc123def456/public",
                "image_url": "https://imagedelivery.net/account-hash/abc123def456/public",
                "image_variants": {
                    "thumbnail": "https://imagedelivery.net/account-hash/abc123def456/thumbnail",
                    "medium": "https://imagedelivery.net/account-hash/abc123def456/medium",
                    "large": "https://imagedelivery.net/account-hash/abc123def456/large",
                    "public": "https://imagedelivery.net/account-hash/abc123def456/public",
                },
                "caption": "Amazing roller coaster photo",
                "alt_text": "Steel roller coaster with multiple inversions",
                "is_primary": True,
                "is_approved": True,
                "photo_type": "exterior",
                "created_at": "2023-01-01T12:00:00Z",
                "updated_at": "2023-01-01T12:00:00Z",
                "date_taken": "2023-01-01T10:00:00Z",
                "uploaded_by_username": "photographer123",
                "file_size": 2048576,
                "dimensions": [1920, 1080],
                "ride_slug": "steel-vengeance",
                "ride_name": "Steel Vengeance",
                "park_slug": "cedar-point",
                "park_name": "Cedar Point",
            },
        )
    ]
)
class RidePhotoOutputSerializer(serializers.ModelSerializer):
    """Output serializer for ride 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 ride 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

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

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


class RidePhotoCreateInputSerializer(serializers.ModelSerializer):
    """Input serializer for creating ride photos."""

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


class RidePhotoUpdateInputSerializer(serializers.ModelSerializer):
    """Input serializer for updating ride photos."""

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


class RidePhotoListOutputSerializer(serializers.ModelSerializer):
    """Simplified output serializer for ride photo lists."""

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

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


class RidePhotoApprovalInputSerializer(serializers.Serializer):
    """Input serializer for 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 RidePhotoStatsOutputSerializer(serializers.Serializer):
    """Output serializer for ride photo statistics."""

    total_photos = serializers.IntegerField()
    approved_photos = serializers.IntegerField()
    pending_photos = serializers.IntegerField()
    has_primary = serializers.BooleanField()
    recent_uploads = serializers.IntegerField()
    by_type = serializers.DictField(child=serializers.IntegerField(), help_text="Photo counts by type")


class RidePhotoTypeFilterSerializer(serializers.Serializer):
    """Serializer for filtering photos by type."""

    photo_type = serializers.ChoiceField(
        choices=[
            ("exterior", "Exterior View"),
            ("queue", "Queue Area"),
            ("station", "Station"),
            ("onride", "On-Ride"),
            ("construction", "Construction"),
            ("other", "Other"),
        ],
        required=False,
        help_text="Filter photos by type",
    )


class RidePhotoSerializer(serializers.ModelSerializer):
    """Legacy serializer for backward compatibility."""

    class Meta:
        model = RidePhoto
        fields = [
            "id",
            "image",
            "caption",
            "alt_text",
            "is_primary",
            "photo_type",
            "uploaded_at",
            "uploaded_by",
        ]


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

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

    # Park location fields
    park_city = serializers.SerializerMethodField()
    park_state = serializers.SerializerMethodField()
    park_country = serializers.SerializerMethodField()

    # Park area fields
    park_area_name = serializers.CharField(source="park_area.name", read_only=True, allow_null=True)
    park_area_slug = serializers.CharField(source="park_area.slug", read_only=True, allow_null=True)

    # Company fields
    manufacturer_name = serializers.CharField(source="manufacturer.name", read_only=True, allow_null=True)
    manufacturer_slug = serializers.CharField(source="manufacturer.slug", read_only=True, allow_null=True)
    designer_name = serializers.CharField(source="designer.name", read_only=True, allow_null=True)
    designer_slug = serializers.CharField(source="designer.slug", read_only=True, allow_null=True)

    # Ride model fields
    ride_model_name = serializers.CharField(source="ride_model.name", read_only=True, allow_null=True)
    ride_model_slug = serializers.CharField(source="ride_model.slug", read_only=True, allow_null=True)
    ride_model_category = serializers.CharField(source="ride_model.category", read_only=True, allow_null=True)
    ride_model_manufacturer_name = serializers.CharField(
        source="ride_model.manufacturer.name", read_only=True, allow_null=True
    )
    ride_model_manufacturer_slug = serializers.CharField(
        source="ride_model.manufacturer.slug", read_only=True, allow_null=True
    )

    # Roller coaster stats fields
    coaster_height_ft = serializers.SerializerMethodField()
    coaster_length_ft = serializers.SerializerMethodField()
    coaster_speed_mph = serializers.SerializerMethodField()
    coaster_inversions = serializers.SerializerMethodField()
    coaster_ride_time_seconds = serializers.SerializerMethodField()
    coaster_track_type = serializers.SerializerMethodField()
    coaster_track_material = serializers.SerializerMethodField()
    coaster_roller_coaster_type = serializers.SerializerMethodField()
    coaster_max_drop_height_ft = serializers.SerializerMethodField()
    coaster_propulsion_system = serializers.SerializerMethodField()
    coaster_train_style = serializers.SerializerMethodField()
    coaster_trains_count = serializers.SerializerMethodField()
    coaster_cars_per_train = serializers.SerializerMethodField()
    coaster_seats_per_car = serializers.SerializerMethodField()

    # Image URLs for display
    banner_image_url = serializers.SerializerMethodField()
    card_image_url = 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_park_city(self, obj):
        """Get city from park location."""
        try:
            if obj.park and hasattr(obj.park, "location") and obj.park.location:
                return obj.park.location.city
            return None
        except AttributeError:
            return None

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

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

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_coaster_height_ft(self, obj):
        """Get roller coaster height."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return float(obj.coaster_stats.height_ft) if obj.coaster_stats.height_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_coaster_length_ft(self, obj):
        """Get roller coaster length."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return float(obj.coaster_stats.length_ft) if obj.coaster_stats.length_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_coaster_speed_mph(self, obj):
        """Get roller coaster speed."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return float(obj.coaster_stats.speed_mph) if obj.coaster_stats.speed_mph else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_coaster_inversions(self, obj):
        """Get roller coaster inversions."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.inversions
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_coaster_ride_time_seconds(self, obj):
        """Get roller coaster ride time."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.ride_time_seconds
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_coaster_track_type(self, obj):
        """Get roller coaster track type."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.track_type
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_coaster_track_material(self, obj):
        """Get roller coaster track material."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.track_material
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_coaster_roller_coaster_type(self, obj):
        """Get roller coaster type."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.roller_coaster_type
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_coaster_max_drop_height_ft(self, obj):
        """Get roller coaster max drop height."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return float(obj.coaster_stats.max_drop_height_ft) if obj.coaster_stats.max_drop_height_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_coaster_propulsion_system(self, obj):
        """Get roller coaster propulsion system."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.propulsion_system
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_coaster_train_style(self, obj):
        """Get roller coaster train style."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.train_style
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_coaster_trains_count(self, obj):
        """Get roller coaster trains count."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.trains_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_coaster_cars_per_train(self, obj):
        """Get roller coaster cars per train."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.cars_per_train
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_coaster_seats_per_car(self, obj):
        """Get roller coaster seats per car."""
        try:
            if hasattr(obj, "coaster_stats") and obj.coaster_stats:
                return obj.coaster_stats.seats_per_car
            return None
        except AttributeError:
            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

    # Computed property
    is_closing = serializers.SerializerMethodField()

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

    # Water ride stats fields
    water_wetness_level = serializers.SerializerMethodField()
    water_splash_height_ft = serializers.SerializerMethodField()
    water_has_splash_zone = serializers.SerializerMethodField()
    water_boat_capacity = serializers.SerializerMethodField()
    water_uses_flume = serializers.SerializerMethodField()
    water_rapids_sections = serializers.SerializerMethodField()

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_water_wetness_level(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return obj.water_stats.wetness_level
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_water_splash_height_ft(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return float(obj.water_stats.splash_height_ft) if obj.water_stats.splash_height_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_water_has_splash_zone(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return obj.water_stats.has_splash_zone
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_water_boat_capacity(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return obj.water_stats.boat_capacity
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_water_uses_flume(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return obj.water_stats.uses_flume
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_water_rapids_sections(self, obj):
        try:
            if hasattr(obj, "water_stats") and obj.water_stats:
                return obj.water_stats.rapids_sections
            return None
        except AttributeError:
            return None

    # Dark ride stats fields
    dark_scene_count = serializers.SerializerMethodField()
    dark_animatronic_count = serializers.SerializerMethodField()
    dark_has_projection_technology = serializers.SerializerMethodField()
    dark_is_interactive = serializers.SerializerMethodField()
    dark_ride_system = serializers.SerializerMethodField()
    dark_uses_practical_effects = serializers.SerializerMethodField()
    dark_uses_motion_base = serializers.SerializerMethodField()

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_dark_scene_count(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.scene_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_dark_animatronic_count(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.animatronic_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_dark_has_projection_technology(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.has_projection_technology
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_dark_is_interactive(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.is_interactive
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_dark_ride_system(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.ride_system
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_dark_uses_practical_effects(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.uses_practical_effects
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_dark_uses_motion_base(self, obj):
        try:
            if hasattr(obj, "dark_stats") and obj.dark_stats:
                return obj.dark_stats.uses_motion_base
            return None
        except AttributeError:
            return None

    # Flat ride stats fields
    flat_max_height_ft = serializers.SerializerMethodField()
    flat_rotation_speed_rpm = serializers.SerializerMethodField()
    flat_swing_angle_degrees = serializers.SerializerMethodField()
    flat_motion_type = serializers.SerializerMethodField()
    flat_arm_count = serializers.SerializerMethodField()
    flat_seats_per_gondola = serializers.SerializerMethodField()
    flat_max_g_force = serializers.SerializerMethodField()

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_flat_max_height_ft(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return float(obj.flat_stats.max_height_ft) if obj.flat_stats.max_height_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_flat_rotation_speed_rpm(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return float(obj.flat_stats.rotation_speed_rpm) if obj.flat_stats.rotation_speed_rpm else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_flat_swing_angle_degrees(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return obj.flat_stats.swing_angle_degrees
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_flat_motion_type(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return obj.flat_stats.motion_type
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_flat_arm_count(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return obj.flat_stats.arm_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_flat_seats_per_gondola(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return obj.flat_stats.seats_per_gondola
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_flat_max_g_force(self, obj):
        try:
            if hasattr(obj, "flat_stats") and obj.flat_stats:
                return float(obj.flat_stats.max_g_force) if obj.flat_stats.max_g_force else None
            return None
        except (AttributeError, TypeError):
            return None

    # Kiddie ride stats fields
    kiddie_min_age = serializers.SerializerMethodField()
    kiddie_max_age = serializers.SerializerMethodField()
    kiddie_educational_theme = serializers.SerializerMethodField()
    kiddie_character_theme = serializers.SerializerMethodField()
    kiddie_guardian_required = serializers.SerializerMethodField()
    kiddie_adult_ride_along = serializers.SerializerMethodField()
    kiddie_seats_per_vehicle = serializers.SerializerMethodField()

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_kiddie_min_age(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.min_age
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_kiddie_max_age(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.max_age
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_kiddie_educational_theme(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.educational_theme or None
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_kiddie_character_theme(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.character_theme or None
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_kiddie_guardian_required(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.guardian_required
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_kiddie_adult_ride_along(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.adult_ride_along
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_kiddie_seats_per_vehicle(self, obj):
        try:
            if hasattr(obj, "kiddie_stats") and obj.kiddie_stats:
                return obj.kiddie_stats.seats_per_vehicle
            return None
        except AttributeError:
            return None

    # Transportation stats fields
    transport_type = serializers.SerializerMethodField()
    transport_route_length_ft = serializers.SerializerMethodField()
    transport_stations_count = serializers.SerializerMethodField()
    transport_vehicle_capacity = serializers.SerializerMethodField()
    transport_vehicles_count = serializers.SerializerMethodField()
    transport_round_trip_duration_minutes = serializers.SerializerMethodField()
    transport_scenic_highlights = serializers.SerializerMethodField()
    transport_is_one_way = serializers.SerializerMethodField()

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_transport_type(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.transport_type
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.FloatField(allow_null=True))
    def get_transport_route_length_ft(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return float(obj.transport_stats.route_length_ft) if obj.transport_stats.route_length_ft else None
            return None
        except (AttributeError, TypeError):
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_transport_stations_count(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.stations_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_transport_vehicle_capacity(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.vehicle_capacity
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_transport_vehicles_count(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.vehicles_count
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.IntegerField(allow_null=True))
    def get_transport_round_trip_duration_minutes(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.round_trip_duration_minutes
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.CharField(allow_null=True))
    def get_transport_scenic_highlights(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.scenic_highlights or None
            return None
        except AttributeError:
            return None

    @extend_schema_field(serializers.BooleanField(allow_null=True))
    def get_transport_is_one_way(self, obj):
        try:
            if hasattr(obj, "transport_stats") and obj.transport_stats:
                return obj.transport_stats.is_one_way
            return None
        except AttributeError:
            return None

    class Meta:
        model = Ride
        fields = [
            # Basic ride info
            "id",
            "name",
            "slug",
            "description",
            "category",
            "status",
            "post_closing_status",
            # Dates and computed fields
            "opening_date",
            "opening_date_precision",
            "closing_date",
            "closing_date_precision",
            "is_closing",
            "status_since",
            "opening_year",
            # Park fields
            "park_name",
            "park_slug",
            "park_city",
            "park_state",
            "park_country",
            # Park area fields
            "park_area_name",
            "park_area_slug",
            # Company fields
            "manufacturer_name",
            "manufacturer_slug",
            "designer_name",
            "designer_slug",
            # Ride model fields
            "ride_model_name",
            "ride_model_slug",
            "ride_model_category",
            "ride_model_manufacturer_name",
            "ride_model_manufacturer_slug",
            # Ride specifications
            "min_height_in",
            "max_height_in",
            "capacity_per_hour",
            "ride_duration_seconds",
            "average_rating",
            # Additional classification
            "ride_sub_type",
            "age_requirement",
            # Roller coaster stats
            "coaster_height_ft",
            "coaster_length_ft",
            "coaster_speed_mph",
            "coaster_inversions",
            "coaster_ride_time_seconds",
            "coaster_track_type",
            "coaster_track_material",
            "coaster_roller_coaster_type",
            "coaster_max_drop_height_ft",
            "coaster_propulsion_system",
            "coaster_train_style",
            "coaster_trains_count",
            "coaster_cars_per_train",
            "coaster_seats_per_car",
            # Water ride stats
            "water_wetness_level",
            "water_splash_height_ft",
            "water_has_splash_zone",
            "water_boat_capacity",
            "water_uses_flume",
            "water_rapids_sections",
            # Dark ride stats
            "dark_scene_count",
            "dark_animatronic_count",
            "dark_has_projection_technology",
            "dark_is_interactive",
            "dark_ride_system",
            "dark_uses_practical_effects",
            "dark_uses_motion_base",
            # Flat ride stats
            "flat_max_height_ft",
            "flat_rotation_speed_rpm",
            "flat_swing_angle_degrees",
            "flat_motion_type",
            "flat_arm_count",
            "flat_seats_per_gondola",
            "flat_max_g_force",
            # Kiddie ride stats
            "kiddie_min_age",
            "kiddie_max_age",
            "kiddie_educational_theme",
            "kiddie_character_theme",
            "kiddie_guardian_required",
            "kiddie_adult_ride_along",
            "kiddie_seats_per_vehicle",
            # Transportation stats
            "transport_type",
            "transport_route_length_ft",
            "transport_stations_count",
            "transport_vehicle_capacity",
            "transport_vehicles_count",
            "transport_round_trip_duration_minutes",
            "transport_scenic_highlights",
            "transport_is_one_way",
            # Images
            "banner_image_url",
            "card_image_url",
            # URLs
            "url",
            "park_url",
            # Computed fields for filtering
            "search_text",
            # Metadata
            "created_at",
            "updated_at",
        ]
        read_only_fields = fields


class RideSerializer(serializers.ModelSerializer):
    """Serializer for the Ride model."""

    class Meta:
        model = Ride
        fields = [
            "id",
            "name",
            "slug",
            "park",
            "manufacturer",
            "designer",
            "category",
            "status",
            "opening_date",
            "closing_date",
        ]
