"""
Full-featured Rides API views for ThrillWiki API v1.

This module implements a "full fat" set of endpoints:
- List / Create: GET /rides/  POST /rides/
- Retrieve / Update / Delete: GET /rides/{pk}/  PATCH/PUT/DELETE
- Filter options: GET /rides/filter-options/
- Company search: GET /rides/search/companies/?q=...
- Ride model search: GET /rides/search-ride-models/?q=...
- Search suggestions: GET /rides/search-suggestions/?q=...
Notes:
- These views try to use real Django models if available. If the domain models/services
  are not present, they return a clear 501 response explaining what to wire up.

Caching Strategy:
- RideListCreateAPIView.get: 10 minutes (600s) - ride lists are frequently queried
- RideDetailAPIView.get: 30 minutes (1800s) - detail views are stable
- FilterOptionsAPIView.get: 30 minutes (1800s) - filter options change rarely
- HybridRideAPIView.get: 10 minutes (600s) - ride lists with filters
- RideFilterMetadataAPIView.get: 30 minutes (1800s) - metadata is stable
- CompanySearchAPIView.get: 10 minutes (600s) - company data is stable
- RideModelSearchAPIView.get: 10 minutes (600s) - ride model data is stable
- RideSearchSuggestionsAPIView.get: 5 minutes (300s) - suggestions should be fresh
"""

import contextlib
import logging
from typing import Any

from django.db import models
from django.db.models import Count
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_view
from rest_framework import permissions, status
from rest_framework.exceptions import NotFound
from rest_framework.pagination import PageNumberPagination
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.api.v1.serializers.rides import (
    RideCreateInputSerializer,
    RideDetailOutputSerializer,
    RideImageSettingsInputSerializer,
    RideListOutputSerializer,
    RideUpdateInputSerializer,
)
from apps.core.decorators.cache_decorators import cache_api_response
from apps.core.utils import capture_and_log
from apps.rides.services.hybrid_loader import SmartRideLoader

logger = logging.getLogger(__name__)

# Create smart loader instance
smart_ride_loader = SmartRideLoader()

# Attempt to import model-level helpers; fall back gracefully if not present.
try:
    from apps.parks.models import Company, Park
    from apps.rides.models import Ride, RideModel
    from apps.rides.models.rides import RollerCoasterStats

    MODELS_AVAILABLE = True
except Exception:
    Ride = None  # type: ignore
    RideModel = None  # type: ignore
    RollerCoasterStats = None  # type: ignore
    Company = None  # type: ignore
    Park = None  # type: ignore
    MODELS_AVAILABLE = False

# Attempt to import ModelChoices to return filter options
try:
    from apps.api.v1.serializers.shared import ModelChoices  # type: ignore

    HAVE_MODELCHOICES = True
except Exception:
    ModelChoices = None  # type: ignore
    HAVE_MODELCHOICES = False


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 20
    page_size_query_param = "page_size"
    max_page_size = 1000


# --- Ride list & create -----------------------------------------------------
class RideListCreateAPIView(APIView):
    """
    API View for listing and creating rides.

    Caching: GET requests are cached for 10 minutes (600s).
    POST requests bypass cache and invalidate related cache entries.
    """

    permission_classes = [permissions.AllowAny]

    @extend_schema(
        summary="List rides with comprehensive filtering and pagination",
        description="List rides with comprehensive filtering options including category, status, manufacturer, designer, ride model, and more.",
        parameters=[
            OpenApiParameter(
                name="page",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Page number for pagination",
            ),
            OpenApiParameter(
                name="page_size",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Number of results per page (max 1000)",
            ),
            OpenApiParameter(
                name="search",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Search in ride names and descriptions",
            ),
            OpenApiParameter(
                name="park_slug",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by park slug",
            ),
            OpenApiParameter(
                name="park_id",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by park ID",
            ),
            OpenApiParameter(
                name="category",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by ride category (RC, DR, FR, WR, TR, OT). Multiple values supported: ?category=RC&category=DR",
            ),
            OpenApiParameter(
                name="status",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by ride status. Multiple values supported: ?status=OPERATING&status=CLOSED_TEMP",
            ),
            OpenApiParameter(
                name="manufacturer_id",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by manufacturer company ID",
            ),
            OpenApiParameter(
                name="manufacturer_slug",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by manufacturer company slug",
            ),
            OpenApiParameter(
                name="designer_id",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by designer company ID",
            ),
            OpenApiParameter(
                name="designer_slug",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by designer company slug",
            ),
            OpenApiParameter(
                name="ride_model_id",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by specific ride model ID",
            ),
            OpenApiParameter(
                name="ride_model_slug",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by ride model slug (requires manufacturer_slug)",
            ),
            OpenApiParameter(
                name="roller_coaster_type",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter roller coasters by type (SITDOWN, INVERTED, FLYING, etc.)",
            ),
            OpenApiParameter(
                name="track_material",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter roller coasters by track material (STEEL, WOOD, HYBRID)",
            ),
            OpenApiParameter(
                name="propulsion_system",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter roller coasters by propulsion system (CHAIN, LSM, HYDRAULIC, etc.)",
            ),
            OpenApiParameter(
                name="min_rating",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter by minimum average rating (1-10)",
            ),
            OpenApiParameter(
                name="max_rating",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter by maximum average rating (1-10)",
            ),
            OpenApiParameter(
                name="min_height_requirement",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by minimum height requirement in inches",
            ),
            OpenApiParameter(
                name="max_height_requirement",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by maximum height requirement in inches",
            ),
            OpenApiParameter(
                name="min_capacity",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by minimum hourly capacity",
            ),
            OpenApiParameter(
                name="max_capacity",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by maximum hourly capacity",
            ),
            OpenApiParameter(
                name="min_height_ft",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter roller coasters by minimum height in feet",
            ),
            OpenApiParameter(
                name="max_height_ft",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter roller coasters by maximum height in feet",
            ),
            OpenApiParameter(
                name="min_speed_mph",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter roller coasters by minimum speed in mph",
            ),
            OpenApiParameter(
                name="max_speed_mph",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.NUMBER,
                description="Filter roller coasters by maximum speed in mph",
            ),
            OpenApiParameter(
                name="min_inversions",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter roller coasters by minimum number of inversions",
            ),
            OpenApiParameter(
                name="max_inversions",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter roller coasters by maximum number of inversions",
            ),
            OpenApiParameter(
                name="has_inversions",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.BOOL,
                description="Filter roller coasters that have inversions (true) or don't have inversions (false)",
            ),
            OpenApiParameter(
                name="opening_year",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by opening year",
            ),
            OpenApiParameter(
                name="min_opening_year",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by minimum opening year",
            ),
            OpenApiParameter(
                name="max_opening_year",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.INT,
                description="Filter by maximum opening year",
            ),
            OpenApiParameter(
                name="ordering",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Order results by field. Options: name, -name, opening_date, -opening_date, average_rating, -average_rating, capacity_per_hour, -capacity_per_hour, created_at, -created_at, height_ft, -height_ft, speed_mph, -speed_mph",
            ),
        ],
        responses={200: RideListOutputSerializer(many=True)},
        tags=["Rides"],
    )
    @cache_api_response(timeout=600, key_prefix="ride_list")
    def get(self, request: Request) -> Response:
        """List rides with comprehensive filtering and pagination."""
        if not MODELS_AVAILABLE:
            return Response(
                {
                    "detail": "Ride listing is not available because domain models are not imported. "
                    "Implement apps.rides.models.Ride (and related managers) to enable listing."
                },
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )

        # Start with base queryset with optimized joins
        qs = (
            Ride.objects.all()
            .select_related(
                "park",
                "manufacturer",
                "designer",
                "ride_model",
                "ride_model__manufacturer",
            )
            .prefetch_related("coaster_stats")
        )  # type: ignore

        # Apply comprehensive filtering
        qs = self._apply_filters(qs, request.query_params)

        # Apply ordering
        qs = self._apply_ordering(qs, request.query_params)

        paginator = StandardResultsSetPagination()
        page = paginator.paginate_queryset(qs, request)
        serializer = RideListOutputSerializer(page, many=True, context={"request": request})
        return paginator.get_paginated_response(serializer.data)

    def _apply_filters(self, qs, params):
        """Apply all filtering to the queryset."""
        qs = self._apply_search_filters(qs, params)
        qs = self._apply_park_filters(qs, params)
        qs = self._apply_category_status_filters(qs, params)
        qs = self._apply_company_filters(qs, params)
        qs = self._apply_ride_model_filters(qs, params)
        qs = self._apply_rating_filters(qs, params)
        qs = self._apply_height_requirement_filters(qs, params)
        qs = self._apply_capacity_filters(qs, params)
        qs = self._apply_opening_year_filters(qs, params)
        qs = self._apply_roller_coaster_filters(qs, params)
        return qs

    def _apply_search_filters(self, qs, params):
        """Apply text search filtering."""
        search = params.get("search")
        if search:
            qs = qs.filter(
                models.Q(name__icontains=search)
                | models.Q(description__icontains=search)
                | models.Q(park__name__icontains=search)
            )
        return qs

    def _apply_park_filters(self, qs, params):
        """Apply park-related filtering."""
        park_slug = params.get("park_slug")
        if park_slug:
            qs = qs.filter(park__slug=park_slug)

        park_id = params.get("park_id")
        if park_id:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(park_id=int(park_id))

        return qs

    def _apply_category_status_filters(self, qs, params):
        """Apply category and status filtering."""
        categories = params.getlist("category")
        if categories:
            qs = qs.filter(category__in=categories)

        statuses = params.getlist("status")
        if statuses:
            qs = qs.filter(status__in=statuses)

        return qs

    def _apply_company_filters(self, qs, params):
        """Apply manufacturer and designer filtering."""
        manufacturer_id = params.get("manufacturer_id")
        if manufacturer_id:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(manufacturer_id=int(manufacturer_id))

        manufacturer_slug = params.get("manufacturer_slug")
        if manufacturer_slug:
            qs = qs.filter(manufacturer__slug=manufacturer_slug)

        designer_id = params.get("designer_id")
        if designer_id:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(designer_id=int(designer_id))

        designer_slug = params.get("designer_slug")
        if designer_slug:
            qs = qs.filter(designer__slug=designer_slug)

        return qs

    def _apply_ride_model_filters(self, qs, params):
        """Apply ride model filtering."""
        ride_model_id = params.get("ride_model_id")
        if ride_model_id:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(ride_model_id=int(ride_model_id))

        ride_model_slug = params.get("ride_model_slug")
        manufacturer_slug_for_model = params.get("manufacturer_slug")
        if ride_model_slug and manufacturer_slug_for_model:
            qs = qs.filter(
                ride_model__slug=ride_model_slug,
                ride_model__manufacturer__slug=manufacturer_slug_for_model,
            )

        return qs

    def _apply_rating_filters(self, qs, params):
        """Apply rating-based filtering."""
        min_rating = params.get("min_rating")
        if min_rating:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(average_rating__gte=float(min_rating))

        max_rating = params.get("max_rating")
        if max_rating:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(average_rating__lte=float(max_rating))

        return qs

    def _apply_height_requirement_filters(self, qs, params):
        """Apply height requirement filtering."""
        min_height_req = params.get("min_height_requirement")
        if min_height_req:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(min_height_in__gte=int(min_height_req))

        max_height_req = params.get("max_height_requirement")
        if max_height_req:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(max_height_in__lte=int(max_height_req))

        return qs

    def _apply_capacity_filters(self, qs, params):
        """Apply capacity filtering."""
        min_capacity = params.get("min_capacity")
        if min_capacity:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(capacity_per_hour__gte=int(min_capacity))

        max_capacity = params.get("max_capacity")
        if max_capacity:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(capacity_per_hour__lte=int(max_capacity))

        return qs

    def _apply_opening_year_filters(self, qs, params):
        """Apply opening year filtering."""
        opening_year = params.get("opening_year")
        if opening_year:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(opening_date__year=int(opening_year))

        min_opening_year = params.get("min_opening_year")
        if min_opening_year:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(opening_date__year__gte=int(min_opening_year))

        max_opening_year = params.get("max_opening_year")
        if max_opening_year:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(opening_date__year__lte=int(max_opening_year))

        return qs

    def _apply_roller_coaster_filters(self, qs, params):
        """Apply roller coaster specific filtering."""
        roller_coaster_type = params.get("roller_coaster_type")
        if roller_coaster_type:
            qs = qs.filter(coaster_stats__roller_coaster_type=roller_coaster_type)

        track_material = params.get("track_material")
        if track_material:
            qs = qs.filter(coaster_stats__track_material=track_material)

        propulsion_system = params.get("propulsion_system")
        if propulsion_system:
            qs = qs.filter(coaster_stats__propulsion_system=propulsion_system)

        # Height filters
        min_height_ft = params.get("min_height_ft")
        if min_height_ft:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__height_ft__gte=float(min_height_ft))

        max_height_ft = params.get("max_height_ft")
        if max_height_ft:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__height_ft__lte=float(max_height_ft))

        # Speed filters
        min_speed_mph = params.get("min_speed_mph")
        if min_speed_mph:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__speed_mph__gte=float(min_speed_mph))

        max_speed_mph = params.get("max_speed_mph")
        if max_speed_mph:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__speed_mph__lte=float(max_speed_mph))

        # Inversion filters
        min_inversions = params.get("min_inversions")
        if min_inversions:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__inversions__gte=int(min_inversions))

        max_inversions = params.get("max_inversions")
        if max_inversions:
            with contextlib.suppress(ValueError, TypeError):
                qs = qs.filter(coaster_stats__inversions__lte=int(max_inversions))

        has_inversions = params.get("has_inversions")
        if has_inversions is not None:
            if has_inversions.lower() in ["true", "1", "yes"]:
                qs = qs.filter(coaster_stats__inversions__gt=0)
            elif has_inversions.lower() in ["false", "0", "no"]:
                qs = qs.filter(coaster_stats__inversions=0)

        return qs

    def _apply_ordering(self, qs, params):
        """Apply ordering to the queryset."""
        ordering = params.get("ordering", "name")
        valid_orderings = [
            "name",
            "-name",
            "opening_date",
            "-opening_date",
            "average_rating",
            "-average_rating",
            "capacity_per_hour",
            "-capacity_per_hour",
            "created_at",
            "-created_at",
            "height_ft",
            "-height_ft",
            "speed_mph",
            "-speed_mph",
        ]

        if ordering in valid_orderings:
            if ordering in ["height_ft", "-height_ft", "speed_mph", "-speed_mph"]:
                # For coaster stats ordering, we need to join and order by the stats
                ordering_field = ordering.replace("height_ft", "coaster_stats__height_ft").replace(
                    "speed_mph", "coaster_stats__speed_mph"
                )
                qs = qs.order_by(ordering_field)
            else:
                qs = qs.order_by(ordering)

        return qs

    @extend_schema(
        summary="Create a new ride",
        description="Create a new ride.",
        responses={201: RideDetailOutputSerializer()},
        tags=["Rides"],
    )
    def post(self, request: Request) -> Response:
        """Create a new ride."""
        serializer_in = RideCreateInputSerializer(data=request.data)
        serializer_in.is_valid(raise_exception=True)

        if not MODELS_AVAILABLE:
            return Response(
                {
                    "detail": "Ride creation is not available because domain models are not imported. "
                    "Implement apps.rides.models.Ride and necessary create logic."
                },
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )

        validated = serializer_in.validated_data

        # Minimal create logic using model fields if available.
        try:
            park = Park.objects.get(id=validated["park_id"])  # type: ignore
        except Park.DoesNotExist:  # type: ignore
            raise NotFound("Park not found") from None

        ride = Ride.objects.create(  # type: ignore
            name=validated["name"],
            description=validated.get("description", ""),
            category=validated.get("category"),
            status=validated.get("status"),
            park=park,
            park_area_id=validated.get("park_area_id"),
            opening_date=validated.get("opening_date"),
            closing_date=validated.get("closing_date"),
            status_since=validated.get("status_since"),
            min_height_in=validated.get("min_height_in"),
            max_height_in=validated.get("max_height_in"),
            capacity_per_hour=validated.get("capacity_per_hour"),
            ride_duration_seconds=validated.get("ride_duration_seconds"),
        )

        # Optional foreign keys
        if validated.get("manufacturer_id"):
            try:
                ride.manufacturer_id = validated["manufacturer_id"]
                ride.save()
            except Exception:
                # ignore if foreign key constraints or models not present
                pass

        out_serializer = RideDetailOutputSerializer(ride, context={"request": request})
        return Response(out_serializer.data, status=status.HTTP_201_CREATED)


# --- Ride retrieve / update / delete ---------------------------------------
@extend_schema(
    summary="Retrieve, update or delete a ride",
    responses={200: RideDetailOutputSerializer()},
    tags=["Rides"],
)
class RideDetailAPIView(APIView):
    """
    API View for retrieving, updating, or deleting a single ride.

    Caching: GET requests are cached for 30 minutes (1800s).
    PATCH/PUT/DELETE requests bypass cache and should trigger cache invalidation.
    """

    permission_classes = [permissions.AllowAny]

    def _get_ride_or_404(self, pk: int) -> Any:
        if not MODELS_AVAILABLE:
            raise NotFound(
                "Ride detail is not available because domain models are not imported. "
                "Implement apps.rides.models.Ride to enable detail endpoints."
            )
        try:
            return Ride.objects.select_related("park").get(pk=pk)  # type: ignore
        except Ride.DoesNotExist:  # type: ignore
            raise NotFound("Ride not found") from None

    @cache_api_response(timeout=1800, key_prefix="ride_detail")
    def get(self, request: Request, pk: int) -> Response:
        ride = self._get_ride_or_404(pk)
        serializer = RideDetailOutputSerializer(ride, context={"request": request})
        return Response(serializer.data)

    def patch(self, request: Request, pk: int) -> Response:
        ride = self._get_ride_or_404(pk)
        serializer_in = RideUpdateInputSerializer(data=request.data, partial=True)
        serializer_in.is_valid(raise_exception=True)
        if not MODELS_AVAILABLE:
            return Response(
                {"detail": "Ride update is not available because domain models are not imported."},
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )

        validated_data = serializer_in.validated_data
        park_change_info = None

        # Handle park change specially if park_id is being updated
        if "park_id" in validated_data:
            new_park_id = validated_data.pop("park_id")
            try:
                new_park = Park.objects.get(id=new_park_id)  # type: ignore
                if new_park.id != ride.park_id:
                    # Use the move_to_park method for proper handling
                    park_change_info = ride.move_to_park(new_park)
            except Park.DoesNotExist:  # type: ignore
                raise NotFound("Target park not found") from None

        # Apply other field updates
        for key, value in validated_data.items():
            setattr(ride, key, value)

        ride.save()

        # Prepare response data
        serializer = RideDetailOutputSerializer(ride, context={"request": request})
        response_data = serializer.data

        # Add park change information to response if applicable
        if park_change_info:
            response_data["park_change_info"] = park_change_info

        return Response(response_data)

    def put(self, request: Request, pk: int) -> Response:
        # Full replace - reuse patch behavior for simplicity
        return self.patch(request, pk)

    def delete(self, request: Request, pk: int) -> Response:
        if not MODELS_AVAILABLE:
            return Response(
                {"detail": "Ride delete is not available because domain models are not imported."},
                status=status.HTTP_501_NOT_IMPLEMENTED,
            )
        ride = self._get_ride_or_404(pk)
        ride.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


# --- Filter options ---------------------------------------------------------
@extend_schema(
    summary="Get comprehensive filter options for rides",
    description="Returns all available filter options for rides with complete read-only access to all possible ride model fields and attributes, including dynamic data from database.",
    responses={200: OpenApiTypes.OBJECT},
    tags=["Rides"],
)
class FilterOptionsAPIView(APIView):
    """
    API View for ride filter options.

    Caching: 30-minute timeout (1800s) - filter options change rarely
    and are expensive to compute.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=1800, key_prefix="ride_filter_options")
    def get(self, request: Request) -> Response:
        """Return comprehensive filter options with Rich Choice Objects metadata."""
        # Import Rich Choice registry
        from apps.core.choices.registry import get_choices

        if not MODELS_AVAILABLE:
            # Use Rich Choice Objects for fallback options
            try:
                # Get rich choice objects from registry
                categories = get_choices("categories", "rides")
                statuses = get_choices("statuses", "rides")
                post_closing_statuses = get_choices("post_closing_statuses", "rides")
                track_materials = get_choices("track_materials", "rides")
                coaster_types = get_choices("coaster_types", "rides")
                propulsion_systems = get_choices("propulsion_systems", "rides")
                target_markets = get_choices("target_markets", "rides")

                # Convert Rich Choice Objects to frontend format with metadata
                categories_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in categories
                ]

                statuses_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in statuses
                ]

                post_closing_statuses_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in post_closing_statuses
                ]

                track_materials_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in track_materials
                ]

                coaster_types_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in coaster_types
                ]

                propulsion_systems_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in propulsion_systems
                ]

                target_markets_data = [
                    {
                        "value": choice.value,
                        "label": choice.label,
                        "description": choice.description,
                        "color": choice.metadata.get("color"),
                        "icon": choice.metadata.get("icon"),
                        "css_class": choice.metadata.get("css_class"),
                        "sort_order": choice.metadata.get("sort_order", 0),
                    }
                    for choice in target_markets
                ]

            except Exception:
                # Ultimate fallback with basic structure
                categories_data = [
                    {
                        "value": "RC",
                        "label": "Roller Coaster",
                        "description": "High-speed thrill rides with tracks",
                        "color": "red",
                        "icon": "roller-coaster",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "DR",
                        "label": "Dark Ride",
                        "description": "Indoor themed experiences",
                        "color": "purple",
                        "icon": "dark-ride",
                        "css_class": "bg-purple-100 text-purple-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "FR",
                        "label": "Flat Ride",
                        "description": "Spinning and rotating attractions",
                        "color": "blue",
                        "icon": "flat-ride",
                        "css_class": "bg-blue-100 text-blue-800",
                        "sort_order": 3,
                    },
                    {
                        "value": "WR",
                        "label": "Water Ride",
                        "description": "Water-based attractions and slides",
                        "color": "cyan",
                        "icon": "water-ride",
                        "css_class": "bg-cyan-100 text-cyan-800",
                        "sort_order": 4,
                    },
                    {
                        "value": "TR",
                        "label": "Transport",
                        "description": "Transportation systems within parks",
                        "color": "green",
                        "icon": "transport",
                        "css_class": "bg-green-100 text-green-800",
                        "sort_order": 5,
                    },
                    {
                        "value": "OT",
                        "label": "Other",
                        "description": "Miscellaneous attractions",
                        "color": "gray",
                        "icon": "other",
                        "css_class": "bg-gray-100 text-gray-800",
                        "sort_order": 6,
                    },
                ]
                statuses_data = [
                    {
                        "value": "OPERATING",
                        "label": "Operating",
                        "description": "Ride is currently open and operating",
                        "color": "green",
                        "icon": "check-circle",
                        "css_class": "bg-green-100 text-green-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "CLOSED_TEMP",
                        "label": "Temporarily Closed",
                        "description": "Ride is temporarily closed for maintenance",
                        "color": "yellow",
                        "icon": "pause-circle",
                        "css_class": "bg-yellow-100 text-yellow-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "SBNO",
                        "label": "Standing But Not Operating",
                        "description": "Ride exists but is not operational",
                        "color": "orange",
                        "icon": "stop-circle",
                        "css_class": "bg-orange-100 text-orange-800",
                        "sort_order": 3,
                    },
                    {
                        "value": "CLOSING",
                        "label": "Closing",
                        "description": "Ride is scheduled to close permanently",
                        "color": "red",
                        "icon": "x-circle",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 4,
                    },
                    {
                        "value": "CLOSED_PERM",
                        "label": "Permanently Closed",
                        "description": "Ride has been permanently closed",
                        "color": "red",
                        "icon": "x-circle",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 5,
                    },
                    {
                        "value": "UNDER_CONSTRUCTION",
                        "label": "Under Construction",
                        "description": "Ride is currently being built",
                        "color": "blue",
                        "icon": "tool",
                        "css_class": "bg-blue-100 text-blue-800",
                        "sort_order": 6,
                    },
                    {
                        "value": "DEMOLISHED",
                        "label": "Demolished",
                        "description": "Ride has been completely removed",
                        "color": "gray",
                        "icon": "trash",
                        "css_class": "bg-gray-100 text-gray-800",
                        "sort_order": 7,
                    },
                    {
                        "value": "RELOCATED",
                        "label": "Relocated",
                        "description": "Ride has been moved to another location",
                        "color": "purple",
                        "icon": "arrow-right",
                        "css_class": "bg-purple-100 text-purple-800",
                        "sort_order": 8,
                    },
                ]
                post_closing_statuses_data = [
                    {
                        "value": "SBNO",
                        "label": "Standing But Not Operating",
                        "description": "Ride exists but is not operational",
                        "color": "orange",
                        "icon": "stop-circle",
                        "css_class": "bg-orange-100 text-orange-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "CLOSED_PERM",
                        "label": "Permanently Closed",
                        "description": "Ride has been permanently closed",
                        "color": "red",
                        "icon": "x-circle",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 2,
                    },
                ]
                track_materials_data = [
                    {
                        "value": "STEEL",
                        "label": "Steel",
                        "description": "Modern steel track construction",
                        "color": "gray",
                        "icon": "steel",
                        "css_class": "bg-gray-100 text-gray-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "WOOD",
                        "label": "Wood",
                        "description": "Traditional wooden track construction",
                        "color": "amber",
                        "icon": "wood",
                        "css_class": "bg-amber-100 text-amber-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "HYBRID",
                        "label": "Hybrid",
                        "description": "Steel track on wooden structure",
                        "color": "orange",
                        "icon": "hybrid",
                        "css_class": "bg-orange-100 text-orange-800",
                        "sort_order": 3,
                    },
                ]
                coaster_types_data = [
                    {
                        "value": "SITDOWN",
                        "label": "Sit Down",
                        "description": "Traditional seated roller coaster",
                        "color": "blue",
                        "icon": "sitdown",
                        "css_class": "bg-blue-100 text-blue-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "INVERTED",
                        "label": "Inverted",
                        "description": "Track above riders, feet dangle",
                        "color": "purple",
                        "icon": "inverted",
                        "css_class": "bg-purple-100 text-purple-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "FLYING",
                        "label": "Flying",
                        "description": "Riders positioned face-down",
                        "color": "sky",
                        "icon": "flying",
                        "css_class": "bg-sky-100 text-sky-800",
                        "sort_order": 3,
                    },
                    {
                        "value": "STANDUP",
                        "label": "Stand Up",
                        "description": "Riders stand during the ride",
                        "color": "green",
                        "icon": "standup",
                        "css_class": "bg-green-100 text-green-800",
                        "sort_order": 4,
                    },
                    {
                        "value": "WING",
                        "label": "Wing",
                        "description": "Seats extend beyond track sides",
                        "color": "indigo",
                        "icon": "wing",
                        "css_class": "bg-indigo-100 text-indigo-800",
                        "sort_order": 5,
                    },
                    {
                        "value": "DIVE",
                        "label": "Dive",
                        "description": "Features steep vertical drops",
                        "color": "red",
                        "icon": "dive",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 6,
                    },
                ]
                propulsion_systems_data = [
                    {
                        "value": "CHAIN",
                        "label": "Chain Lift",
                        "description": "Traditional chain lift hill",
                        "color": "gray",
                        "icon": "chain",
                        "css_class": "bg-gray-100 text-gray-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "LSM",
                        "label": "LSM Launch",
                        "description": "Linear synchronous motor launch",
                        "color": "blue",
                        "icon": "lightning",
                        "css_class": "bg-blue-100 text-blue-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "HYDRAULIC",
                        "label": "Hydraulic Launch",
                        "description": "High-pressure hydraulic launch",
                        "color": "red",
                        "icon": "hydraulic",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 3,
                    },
                    {
                        "value": "GRAVITY",
                        "label": "Gravity",
                        "description": "Gravity-powered ride",
                        "color": "green",
                        "icon": "gravity",
                        "css_class": "bg-green-100 text-green-800",
                        "sort_order": 4,
                    },
                ]
                target_markets_data = [
                    {
                        "value": "FAMILY",
                        "label": "Family",
                        "description": "Suitable for all family members",
                        "color": "green",
                        "icon": "family",
                        "css_class": "bg-green-100 text-green-800",
                        "sort_order": 1,
                    },
                    {
                        "value": "THRILL",
                        "label": "Thrill",
                        "description": "High-intensity thrill experience",
                        "color": "orange",
                        "icon": "thrill",
                        "css_class": "bg-orange-100 text-orange-800",
                        "sort_order": 2,
                    },
                    {
                        "value": "EXTREME",
                        "label": "Extreme",
                        "description": "Maximum intensity experience",
                        "color": "red",
                        "icon": "extreme",
                        "css_class": "bg-red-100 text-red-800",
                        "sort_order": 3,
                    },
                    {
                        "value": "KIDDIE",
                        "label": "Kiddie",
                        "description": "Designed for young children",
                        "color": "pink",
                        "icon": "kiddie",
                        "css_class": "bg-pink-100 text-pink-800",
                        "sort_order": 4,
                    },
                    {
                        "value": "ALL_AGES",
                        "label": "All Ages",
                        "description": "Enjoyable for all age groups",
                        "color": "blue",
                        "icon": "all-ages",
                        "css_class": "bg-blue-100 text-blue-800",
                        "sort_order": 5,
                    },
                ]

            # Comprehensive fallback options with Rich Choice Objects metadata
            return Response(
                {
                    "categories": categories_data,
                    "statuses": statuses_data,
                    "post_closing_statuses": [
                        {"value": "SBNO", "label": "Standing But Not Operating"},
                        {"value": "CLOSED_PERM", "label": "Permanently Closed"},
                    ],
                    "roller_coaster_types": [
                        {"value": "SITDOWN", "label": "Sit Down"},
                        {"value": "INVERTED", "label": "Inverted"},
                        {"value": "FLYING", "label": "Flying"},
                        {"value": "STANDUP", "label": "Stand Up"},
                        {"value": "WING", "label": "Wing"},
                        {"value": "DIVE", "label": "Dive"},
                        {"value": "FAMILY", "label": "Family"},
                        {"value": "WILD_MOUSE", "label": "Wild Mouse"},
                        {"value": "SPINNING", "label": "Spinning"},
                        {"value": "FOURTH_DIMENSION", "label": "4th Dimension"},
                        {"value": "OTHER", "label": "Other"},
                    ],
                    "track_materials": [
                        {"value": "STEEL", "label": "Steel"},
                        {"value": "WOOD", "label": "Wood"},
                        {"value": "HYBRID", "label": "Hybrid"},
                    ],
                    "propulsion_systems": [
                        {"value": "CHAIN", "label": "Chain Lift"},
                        {"value": "LSM", "label": "LSM Launch"},
                        {"value": "HYDRAULIC", "label": "Hydraulic Launch"},
                        {"value": "GRAVITY", "label": "Gravity"},
                        {"value": "OTHER", "label": "Other"},
                    ],
                    "ride_model_target_markets": [
                        {"value": "FAMILY", "label": "Family"},
                        {"value": "THRILL", "label": "Thrill"},
                        {"value": "EXTREME", "label": "Extreme"},
                        {"value": "KIDDIE", "label": "Kiddie"},
                        {"value": "ALL_AGES", "label": "All Ages"},
                    ],
                    "parks": [],
                    "park_areas": [],
                    "manufacturers": [],
                    "designers": [],
                    "ride_models": [],
                    "ranges": {
                        "rating": {"min": 1, "max": 10, "step": 0.1, "unit": "stars"},
                        "height_requirement": {
                            "min": 30,
                            "max": 90,
                            "step": 1,
                            "unit": "inches",
                        },
                        "capacity": {
                            "min": 0,
                            "max": 5000,
                            "step": 50,
                            "unit": "riders/hour",
                        },
                        "ride_duration": {
                            "min": 0,
                            "max": 600,
                            "step": 10,
                            "unit": "seconds",
                        },
                        "height_ft": {"min": 0, "max": 500, "step": 5, "unit": "feet"},
                        "length_ft": {
                            "min": 0,
                            "max": 10000,
                            "step": 100,
                            "unit": "feet",
                        },
                        "speed_mph": {"min": 0, "max": 150, "step": 5, "unit": "mph"},
                        "inversions": {
                            "min": 0,
                            "max": 20,
                            "step": 1,
                            "unit": "inversions",
                        },
                        "ride_time": {
                            "min": 0,
                            "max": 600,
                            "step": 10,
                            "unit": "seconds",
                        },
                        "max_drop_height_ft": {
                            "min": 0,
                            "max": 500,
                            "step": 10,
                            "unit": "feet",
                        },
                        "trains_count": {
                            "min": 1,
                            "max": 10,
                            "step": 1,
                            "unit": "trains",
                        },
                        "cars_per_train": {
                            "min": 1,
                            "max": 20,
                            "step": 1,
                            "unit": "cars",
                        },
                        "seats_per_car": {
                            "min": 1,
                            "max": 8,
                            "step": 1,
                            "unit": "seats",
                        },
                        "opening_year": {
                            "min": 1800,
                            "max": 2030,
                            "step": 1,
                            "unit": "year",
                        },
                    },
                    "boolean_filters": [
                        {
                            "key": "has_inversions",
                            "label": "Has Inversions",
                            "description": "Filter roller coasters with or without inversions",
                        },
                        {
                            "key": "has_coordinates",
                            "label": "Has Location Coordinates",
                            "description": "Filter rides with GPS coordinates",
                        },
                        {
                            "key": "has_ride_model",
                            "label": "Has Ride Model",
                            "description": "Filter rides with specified ride model",
                        },
                        {
                            "key": "has_manufacturer",
                            "label": "Has Manufacturer",
                            "description": "Filter rides with specified manufacturer",
                        },
                        {
                            "key": "has_designer",
                            "label": "Has Designer",
                            "description": "Filter rides with specified designer",
                        },
                    ],
                    "ordering_options": [
                        {"value": "name", "label": "Name (A-Z)"},
                        {"value": "-name", "label": "Name (Z-A)"},
                        {
                            "value": "opening_date",
                            "label": "Opening Date (Oldest First)",
                        },
                        {
                            "value": "-opening_date",
                            "label": "Opening Date (Newest First)",
                        },
                        {"value": "average_rating", "label": "Rating (Lowest First)"},
                        {"value": "-average_rating", "label": "Rating (Highest First)"},
                        {
                            "value": "capacity_per_hour",
                            "label": "Capacity (Lowest First)",
                        },
                        {
                            "value": "-capacity_per_hour",
                            "label": "Capacity (Highest First)",
                        },
                        {
                            "value": "ride_duration_seconds",
                            "label": "Duration (Shortest First)",
                        },
                        {
                            "value": "-ride_duration_seconds",
                            "label": "Duration (Longest First)",
                        },
                        {"value": "height_ft", "label": "Height (Shortest First)"},
                        {"value": "-height_ft", "label": "Height (Tallest First)"},
                        {"value": "length_ft", "label": "Length (Shortest First)"},
                        {"value": "-length_ft", "label": "Length (Longest First)"},
                        {"value": "speed_mph", "label": "Speed (Slowest First)"},
                        {"value": "-speed_mph", "label": "Speed (Fastest First)"},
                        {"value": "inversions", "label": "Inversions (Fewest First)"},
                        {"value": "-inversions", "label": "Inversions (Most First)"},
                        {"value": "created_at", "label": "Date Added (Oldest First)"},
                        {"value": "-created_at", "label": "Date Added (Newest First)"},
                        {"value": "updated_at", "label": "Last Updated (Oldest First)"},
                        {
                            "value": "-updated_at",
                            "label": "Last Updated (Newest First)",
                        },
                    ],
                }
            )

        # Get static choice definitions from Rich Choice Objects (primary source)
        # Get dynamic data from database queries

        # Get rich choice objects from registry
        categories = get_choices("categories", "rides")
        statuses = get_choices("statuses", "rides")
        post_closing_statuses = get_choices("post_closing_statuses", "rides")
        track_materials = get_choices("track_materials", "rides")
        coaster_types = get_choices("coaster_types", "rides")
        propulsion_systems = get_choices("propulsion_systems", "rides")
        target_markets = get_choices("target_markets", "rides")

        # Convert Rich Choice Objects to frontend format with metadata
        categories_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in categories
        ]

        statuses_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in statuses
        ]

        post_closing_statuses_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in post_closing_statuses
        ]

        track_materials_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in track_materials
        ]

        coaster_types_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in coaster_types
        ]

        propulsion_systems_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in propulsion_systems
        ]

        target_markets_data = [
            {
                "value": choice.value,
                "label": choice.label,
                "description": choice.description,
                "color": choice.metadata.get("color"),
                "icon": choice.metadata.get("icon"),
                "css_class": choice.metadata.get("css_class"),
                "sort_order": choice.metadata.get("sort_order", 0),
            }
            for choice in target_markets
        ]

        # Get parks data from database
        parks = list(
            Ride.objects.exclude(park__isnull=True)
            .select_related("park")
            .values("park__id", "park__name", "park__slug")
            .distinct()
            .order_by("park__name")
        )

        # Get park areas data from database
        park_areas = list(
            Ride.objects.exclude(park_area__isnull=True)
            .select_related("park_area")
            .values("park_area__id", "park_area__name", "park_area__slug")
            .distinct()
            .order_by("park_area__name")
        )

        # Get manufacturers (companies with MANUFACTURER role)
        manufacturers = list(
            Company.objects.filter(roles__contains=["MANUFACTURER"]).values("id", "name", "slug").order_by("name")
        )

        # Get designers (companies with DESIGNER role)
        designers = list(
            Company.objects.filter(roles__contains=["DESIGNER"]).values("id", "name", "slug").order_by("name")
        )

        # Get ride models data from database
        ride_models = list(
            RideModel.objects.select_related("manufacturer")
            .values(
                "id",
                "name",
                "slug",
                "manufacturer__name",
                "manufacturer__slug",
                "category",
            )
            .order_by("manufacturer__name", "name")
        )

        # Calculate ranges from actual data
        ride_stats = Ride.objects.aggregate(
            min_rating=models.Min("average_rating"),
            max_rating=models.Max("average_rating"),
            min_height_req=models.Min("min_height_in"),
            max_height_req=models.Max("max_height_in"),
            min_capacity=models.Min("capacity_per_hour"),
            max_capacity=models.Max("capacity_per_hour"),
            min_duration=models.Min("ride_duration_seconds"),
            max_duration=models.Max("ride_duration_seconds"),
            min_year=models.Min("opening_date__year"),
            max_year=models.Max("opening_date__year"),
        )

        # Calculate roller coaster specific ranges
        coaster_stats = RollerCoasterStats.objects.aggregate(
            min_height_ft=models.Min("height_ft"),
            max_height_ft=models.Max("height_ft"),
            min_length_ft=models.Min("length_ft"),
            max_length_ft=models.Max("length_ft"),
            min_speed_mph=models.Min("speed_mph"),
            max_speed_mph=models.Max("speed_mph"),
            min_inversions=models.Min("inversions"),
            max_inversions=models.Max("inversions"),
            min_ride_time=models.Min("ride_time_seconds"),
            max_ride_time=models.Max("ride_time_seconds"),
            min_drop_height=models.Min("max_drop_height_ft"),
            max_drop_height=models.Max("max_drop_height_ft"),
            min_trains=models.Min("trains_count"),
            max_trains=models.Max("trains_count"),
            min_cars=models.Min("cars_per_train"),
            max_cars=models.Max("cars_per_train"),
            min_seats=models.Min("seats_per_car"),
            max_seats=models.Max("seats_per_car"),
        )

        ranges = {
            "rating": {
                "min": float(ride_stats["min_rating"] or 1),
                "max": float(ride_stats["max_rating"] or 10),
                "step": 0.1,
                "unit": "stars",
            },
            "height_requirement": {
                "min": ride_stats["min_height_req"] or 30,
                "max": ride_stats["max_height_req"] or 90,
                "step": 1,
                "unit": "inches",
            },
            "capacity": {
                "min": ride_stats["min_capacity"] or 0,
                "max": ride_stats["max_capacity"] or 5000,
                "step": 50,
                "unit": "riders/hour",
            },
            "ride_duration": {
                "min": ride_stats["min_duration"] or 0,
                "max": ride_stats["max_duration"] or 600,
                "step": 10,
                "unit": "seconds",
            },
            "height_ft": {
                "min": float(coaster_stats["min_height_ft"] or 0),
                "max": float(coaster_stats["max_height_ft"] or 500),
                "step": 5,
                "unit": "feet",
            },
            "length_ft": {
                "min": float(coaster_stats["min_length_ft"] or 0),
                "max": float(coaster_stats["max_length_ft"] or 10000),
                "step": 100,
                "unit": "feet",
            },
            "speed_mph": {
                "min": float(coaster_stats["min_speed_mph"] or 0),
                "max": float(coaster_stats["max_speed_mph"] or 150),
                "step": 5,
                "unit": "mph",
            },
            "inversions": {
                "min": coaster_stats["min_inversions"] or 0,
                "max": coaster_stats["max_inversions"] or 20,
                "step": 1,
                "unit": "inversions",
            },
            "ride_time": {
                "min": coaster_stats["min_ride_time"] or 0,
                "max": coaster_stats["max_ride_time"] or 600,
                "step": 10,
                "unit": "seconds",
            },
            "max_drop_height_ft": {
                "min": float(coaster_stats["min_drop_height"] or 0),
                "max": float(coaster_stats["max_drop_height"] or 500),
                "step": 10,
                "unit": "feet",
            },
            "trains_count": {
                "min": coaster_stats["min_trains"] or 1,
                "max": coaster_stats["max_trains"] or 10,
                "step": 1,
                "unit": "trains",
            },
            "cars_per_train": {
                "min": coaster_stats["min_cars"] or 1,
                "max": coaster_stats["max_cars"] or 20,
                "step": 1,
                "unit": "cars",
            },
            "seats_per_car": {
                "min": coaster_stats["min_seats"] or 1,
                "max": coaster_stats["max_seats"] or 8,
                "step": 1,
                "unit": "seats",
            },
            "opening_year": {
                "min": ride_stats["min_year"] or 1800,
                "max": ride_stats["max_year"] or 2030,
                "step": 1,
                "unit": "year",
            },
        }

        return Response(
            {
                "categories": categories_data,
                "statuses": statuses_data,
                "post_closing_statuses": post_closing_statuses_data,
                "roller_coaster_types": coaster_types_data,
                "track_materials": track_materials_data,
                "propulsion_systems": propulsion_systems_data,
                "ride_model_target_markets": target_markets_data,
                "parks": parks,
                "park_areas": park_areas,
                "manufacturers": manufacturers,
                "designers": designers,
                "ride_models": ride_models,
                "ranges": ranges,
                "boolean_filters": [
                    {
                        "key": "has_inversions",
                        "label": "Has Inversions",
                        "description": "Filter roller coasters with or without inversions",
                    },
                    {
                        "key": "has_coordinates",
                        "label": "Has Location Coordinates",
                        "description": "Filter rides with GPS coordinates",
                    },
                    {
                        "key": "has_ride_model",
                        "label": "Has Ride Model",
                        "description": "Filter rides with specified ride model",
                    },
                    {
                        "key": "has_manufacturer",
                        "label": "Has Manufacturer",
                        "description": "Filter rides with specified manufacturer",
                    },
                    {
                        "key": "has_designer",
                        "label": "Has Designer",
                        "description": "Filter rides with specified designer",
                    },
                ],
                "ordering_options": [
                    {"value": "name", "label": "Name (A-Z)"},
                    {"value": "-name", "label": "Name (Z-A)"},
                    {"value": "opening_date", "label": "Opening Date (Oldest First)"},
                    {"value": "-opening_date", "label": "Opening Date (Newest First)"},
                    {"value": "average_rating", "label": "Rating (Lowest First)"},
                    {"value": "-average_rating", "label": "Rating (Highest First)"},
                    {"value": "capacity_per_hour", "label": "Capacity (Lowest First)"},
                    {
                        "value": "-capacity_per_hour",
                        "label": "Capacity (Highest First)",
                    },
                    {
                        "value": "ride_duration_seconds",
                        "label": "Duration (Shortest First)",
                    },
                    {
                        "value": "-ride_duration_seconds",
                        "label": "Duration (Longest First)",
                    },
                    {"value": "height_ft", "label": "Height (Shortest First)"},
                    {"value": "-height_ft", "label": "Height (Tallest First)"},
                    {"value": "length_ft", "label": "Length (Shortest First)"},
                    {"value": "-length_ft", "label": "Length (Longest First)"},
                    {"value": "speed_mph", "label": "Speed (Slowest First)"},
                    {"value": "-speed_mph", "label": "Speed (Fastest First)"},
                    {"value": "inversions", "label": "Inversions (Fewest First)"},
                    {"value": "-inversions", "label": "Inversions (Most First)"},
                    {"value": "created_at", "label": "Date Added (Oldest First)"},
                    {"value": "-created_at", "label": "Date Added (Newest First)"},
                    {"value": "updated_at", "label": "Last Updated (Oldest First)"},
                    {"value": "-updated_at", "label": "Last Updated (Newest First)"},
                ],
            }
        )


# --- Company search (autocomplete) -----------------------------------------
@extend_schema(
    summary="Search companies (manufacturers/designers) for autocomplete",
    parameters=[OpenApiParameter(name="q", location=OpenApiParameter.QUERY, type=OpenApiTypes.STR)],
    responses={200: OpenApiTypes.OBJECT},
    tags=["Rides"],
)
class CompanySearchAPIView(APIView):
    """
    Caching: 10-minute timeout (600s) - company data is stable.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=600, key_prefix="company_search")
    def get(self, request: Request) -> Response:
        q = request.query_params.get("q", "")
        if not q:
            return Response([], status=status.HTTP_200_OK)

        if Company is None:
            # Provide helpful placeholder structure
            return Response(
                [
                    {"id": 1, "name": "Rocky Mountain Construction", "slug": "rmc"},
                    {"id": 2, "name": "Bolliger & Mabillard", "slug": "b&m"},
                ]
            )

        qs = Company.objects.filter(name__icontains=q)[:20]  # type: ignore
        results = [{"id": c.id, "name": c.name, "slug": getattr(c, "slug", "")} for c in qs]
        return Response(results)


# --- Ride model search (autocomplete) --------------------------------------
@extend_schema(
    summary="Search ride models for autocomplete",
    parameters=[OpenApiParameter(name="q", location=OpenApiParameter.QUERY, type=OpenApiTypes.STR)],
    tags=["Rides"],
)
class RideModelSearchAPIView(APIView):
    """
    Caching: 10-minute timeout (600s) - ride model data is stable.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=600, key_prefix="ride_model_search")
    def get(self, request: Request) -> Response:
        q = request.query_params.get("q", "")
        if not q:
            return Response([], status=status.HTTP_200_OK)

        if RideModel is None:
            return Response(
                [
                    {"id": 1, "name": "I-Box (RMC)", "category": "ROLLER_COASTER"},
                    {
                        "id": 2,
                        "name": "Hyper Coaster Model X",
                        "category": "ROLLER_COASTER",
                    },
                ]
            )

        qs = RideModel.objects.filter(name__icontains=q)[:20]  # type: ignore
        results = [{"id": m.id, "name": m.name, "category": getattr(m, "category", "")} for m in qs]
        return Response(results)


# --- Search suggestions -----------------------------------------------------
@extend_schema(
    summary="Search suggestions for ride search box",
    parameters=[OpenApiParameter(name="q", location=OpenApiParameter.QUERY, type=OpenApiTypes.STR)],
    tags=["Rides"],
)
class RideSearchSuggestionsAPIView(APIView):
    """
    Caching: 5-minute timeout (300s) - suggestions should be relatively fresh.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=300, key_prefix="ride_suggestions")
    def get(self, request: Request) -> Response:
        q = request.query_params.get("q", "")
        if not q:
            return Response([], status=status.HTTP_200_OK)

        # Very small suggestion implementation: look in ride names if available
        if MODELS_AVAILABLE and Ride is not None:
            qs = Ride.objects.filter(name__icontains=q).values_list("name", flat=True)[:10]  # type: ignore
            return Response([{"suggestion": name} for name in qs])

        # Fallback suggestions
        fallback = [
            {"suggestion": f"{q} coaster"},
            {"suggestion": f"{q} ride"},
            {"suggestion": f"{q} park"},
        ]
        return Response(fallback)


# --- Ride image settings ---------------------------------------------------
@extend_schema(
    summary="Set ride banner and card images",
    description="Set banner_image and card_image for a ride from existing ride photos",
    request=RideImageSettingsInputSerializer,
    responses={
        200: RideDetailOutputSerializer,
        400: OpenApiTypes.OBJECT,
        404: OpenApiTypes.OBJECT,
    },
    tags=["Rides"],
)
class RideImageSettingsAPIView(APIView):
    permission_classes = [permissions.AllowAny]

    def _get_ride_or_404(self, pk: int) -> Any:
        if not MODELS_AVAILABLE:
            raise NotFound("Ride models not available")
        try:
            return Ride.objects.get(pk=pk)  # type: ignore
        except Ride.DoesNotExist:  # type: ignore
            raise NotFound("Ride not found") from None

    def patch(self, request: Request, pk: int) -> Response:
        """Set banner and card images for the ride."""
        ride = self._get_ride_or_404(pk)

        serializer = RideImageSettingsInputSerializer(data=request.data, partial=True)
        serializer.is_valid(raise_exception=True)

        # Update the ride with the validated data
        for field, value in serializer.validated_data.items():
            setattr(ride, field, value)

        ride.save()

        # Return updated ride data
        output_serializer = RideDetailOutputSerializer(ride, context={"request": request})
        return Response(output_serializer.data)


# --- Hybrid Filtering API Views --------------------------------------------


@extend_schema_view(
    get=extend_schema(
        summary="Get rides with hybrid filtering",
        description="Retrieve rides with intelligent hybrid filtering strategy. Automatically chooses between client-side and server-side filtering based on data size.",
        parameters=[
            OpenApiParameter(
                "category",
                OpenApiTypes.STR,
                description="Filter by ride category (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "status",
                OpenApiTypes.STR,
                description="Filter by ride status (comma-separated for multiple)",
            ),
            OpenApiParameter("park_slug", OpenApiTypes.STR, description="Filter by park slug"),
            OpenApiParameter("park_id", OpenApiTypes.INT, description="Filter by park ID"),
            OpenApiParameter(
                "manufacturer",
                OpenApiTypes.STR,
                description="Filter by manufacturer slug (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "designer",
                OpenApiTypes.STR,
                description="Filter by designer slug (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "ride_model",
                OpenApiTypes.STR,
                description="Filter by ride model slug (comma-separated for multiple)",
            ),
            OpenApiParameter("opening_year_min", OpenApiTypes.INT, description="Minimum opening year"),
            OpenApiParameter("opening_year_max", OpenApiTypes.INT, description="Maximum opening year"),
            OpenApiParameter("rating_min", OpenApiTypes.NUMBER, description="Minimum average rating"),
            OpenApiParameter("rating_max", OpenApiTypes.NUMBER, description="Maximum average rating"),
            OpenApiParameter(
                "height_requirement_min",
                OpenApiTypes.INT,
                description="Minimum height requirement in inches",
            ),
            OpenApiParameter(
                "height_requirement_max",
                OpenApiTypes.INT,
                description="Maximum height requirement in inches",
            ),
            OpenApiParameter("capacity_min", OpenApiTypes.INT, description="Minimum hourly capacity"),
            OpenApiParameter("capacity_max", OpenApiTypes.INT, description="Maximum hourly capacity"),
            OpenApiParameter(
                "roller_coaster_type",
                OpenApiTypes.STR,
                description="Filter by roller coaster type (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "track_material",
                OpenApiTypes.STR,
                description="Filter by track material (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "propulsion_system",
                OpenApiTypes.STR,
                description="Filter by propulsion system (comma-separated for multiple)",
            ),
            OpenApiParameter(
                "height_ft_min",
                OpenApiTypes.NUMBER,
                description="Minimum roller coaster height in feet",
            ),
            OpenApiParameter(
                "height_ft_max",
                OpenApiTypes.NUMBER,
                description="Maximum roller coaster height in feet",
            ),
            OpenApiParameter(
                "speed_mph_min",
                OpenApiTypes.NUMBER,
                description="Minimum roller coaster speed in mph",
            ),
            OpenApiParameter(
                "speed_mph_max",
                OpenApiTypes.NUMBER,
                description="Maximum roller coaster speed in mph",
            ),
            OpenApiParameter(
                "inversions_min",
                OpenApiTypes.INT,
                description="Minimum number of inversions",
            ),
            OpenApiParameter(
                "inversions_max",
                OpenApiTypes.INT,
                description="Maximum number of inversions",
            ),
            OpenApiParameter(
                "has_inversions",
                OpenApiTypes.BOOL,
                description="Filter rides with inversions (true) or without (false)",
            ),
            OpenApiParameter(
                "search",
                OpenApiTypes.STR,
                description="Search query for ride names, descriptions, parks, and related data",
            ),
            OpenApiParameter(
                "offset",
                OpenApiTypes.INT,
                description="Offset for progressive loading (server-side pagination)",
            ),
        ],
        responses={
            200: {
                "description": "Rides data with hybrid filtering metadata",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "rides": {
                                    "type": "array",
                                    "items": {"$ref": "#/components/schemas/HybridRideSerializer"},
                                },
                                "total_count": {"type": "integer"},
                                "strategy": {
                                    "type": "string",
                                    "enum": ["client_side", "server_side"],
                                    "description": "Filtering strategy used",
                                },
                                "has_more": {
                                    "type": "boolean",
                                    "description": "Whether more data is available for progressive loading",
                                },
                                "next_offset": {
                                    "type": "integer",
                                    "nullable": True,
                                    "description": "Next offset for progressive loading",
                                },
                                "filter_metadata": {
                                    "type": "object",
                                    "description": "Available filter options and ranges",
                                },
                            },
                        }
                    }
                },
            }
        },
        tags=["Rides"],
    )
)
class HybridRideAPIView(APIView):
    """
    Hybrid Ride API View with intelligent filtering strategy.

    Automatically chooses between client-side and server-side filtering
    based on data size and complexity. Provides progressive loading
    for large datasets and complete data for smaller sets.

    Caching: 10-minute timeout (600s) - ride lists are frequently queried
    but need to reflect new additions within reasonable time.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=600, key_prefix="hybrid_rides")
    def get(self, request):
        """Get rides with hybrid filtering strategy."""
        try:
            # Extract filters from query parameters
            filters = self._extract_filters(request.query_params)

            # Check if this is a progressive load request
            offset = request.query_params.get("offset")
            if offset is not None:
                try:
                    offset = int(offset)
                    # Get progressive load data
                    data = smart_ride_loader.get_progressive_load(offset, filters)
                except ValueError:
                    return Response(
                        {"detail": "Invalid offset parameter"},
                        status=status.HTTP_400_BAD_REQUEST,
                    )
            else:
                # Get initial load data
                data = smart_ride_loader.get_initial_load(filters)

            # Prepare response (rides are already serialized by the service)
            response_data = {
                "rides": data["rides"],
                "total_count": data["total_count"],
                "strategy": data.get("strategy", "server_side"),
                "has_more": data.get("has_more", False),
                "next_offset": data.get("next_offset"),
            }

            # Include filter metadata for initial loads
            if "filter_metadata" in data:
                response_data["filter_metadata"] = data["filter_metadata"]

            return Response(response_data, status=status.HTTP_200_OK)

        except Exception as e:
            capture_and_log(e, 'Get hybrid rides', source='api')
            return Response(
                {"detail": "Internal server error"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )

    def _extract_filters(self, query_params):
        """Extract and parse filters from query parameters."""
        filters = {}

        # Handle comma-separated list parameters
        list_params = [
            "category",
            "status",
            "manufacturer",
            "designer",
            "ride_model",
            "roller_coaster_type",
            "track_material",
            "propulsion_system",
        ]
        for param in list_params:
            value = query_params.get(param)
            if value:
                filters[param] = [v.strip() for v in value.split(",") if v.strip()]

        # Handle single value parameters
        single_params = ["park_slug", "park_id"]
        for param in single_params:
            value = query_params.get(param)
            if value:
                if param == "park_id":
                    with contextlib.suppress(ValueError):
                        filters[param] = int(value)
                else:
                    filters[param] = value

        # Handle integer parameters
        int_params = [
            "opening_year_min",
            "opening_year_max",
            "height_requirement_min",
            "height_requirement_max",
            "capacity_min",
            "capacity_max",
            "inversions_min",
            "inversions_max",
        ]
        for param in int_params:
            value = query_params.get(param)
            if value:
                try:  # noqa: SIM105
                    filters[param] = int(value)
                except ValueError:
                    pass  # Skip invalid integer values

        # Handle float parameters
        float_params = [
            "rating_min",
            "rating_max",
            "height_ft_min",
            "height_ft_max",
            "speed_mph_min",
            "speed_mph_max",
        ]
        for param in float_params:
            value = query_params.get(param)
            if value:
                try:  # noqa: SIM105
                    filters[param] = float(value)
                except ValueError:
                    pass  # Skip invalid float values

        # Handle boolean parameters
        has_inversions = query_params.get("has_inversions")
        if has_inversions is not None:
            if has_inversions.lower() in ["true", "1", "yes"]:
                filters["has_inversions"] = True
            elif has_inversions.lower() in ["false", "0", "no"]:
                filters["has_inversions"] = False

        # Handle search parameter
        search = query_params.get("search")
        if search:
            filters["search"] = search.strip()

        return filters


@extend_schema_view(
    get=extend_schema(
        summary="Get ride filter metadata",
        description="Get available filter options and ranges for rides filtering.",
        parameters=[
            OpenApiParameter(
                "scoped",
                OpenApiTypes.BOOL,
                description="Whether to scope metadata to current filters",
            ),
        ],
        responses={
            200: {
                "description": "Filter metadata",
                "content": {
                    "application/json": {
                        "schema": {
                            "type": "object",
                            "properties": {
                                "categorical": {
                                    "type": "object",
                                    "properties": {
                                        "categories": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                        },
                                        "statuses": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                        },
                                        "roller_coaster_types": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                        },
                                        "track_materials": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                        },
                                        "propulsion_systems": {
                                            "type": "array",
                                            "items": {"type": "string"},
                                        },
                                        "parks": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "name": {"type": "string"},
                                                    "slug": {"type": "string"},
                                                },
                                            },
                                        },
                                        "manufacturers": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "name": {"type": "string"},
                                                    "slug": {"type": "string"},
                                                },
                                            },
                                        },
                                        "designers": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "name": {"type": "string"},
                                                    "slug": {"type": "string"},
                                                },
                                            },
                                        },
                                    },
                                },
                                "ranges": {
                                    "type": "object",
                                    "properties": {
                                        "opening_year": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "rating": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "height_requirement": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "capacity": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "height_ft": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "speed_mph": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "number",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                        "inversions": {
                                            "type": "object",
                                            "properties": {
                                                "min": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                                "max": {
                                                    "type": "integer",
                                                    "nullable": True,
                                                },
                                            },
                                        },
                                    },
                                },
                                "total_count": {"type": "integer"},
                            },
                        }
                    }
                },
            }
        },
        tags=["Rides"],
    )
)
class RideFilterMetadataAPIView(APIView):
    """
    API view for getting ride filter metadata.

    Provides information about available filter options and ranges
    to help build dynamic filter interfaces.

    Caching: 30-minute timeout (1800s) - filter metadata is stable
    and only changes when new entities are added.
    """

    permission_classes = [permissions.AllowAny]

    @cache_api_response(timeout=1800, key_prefix="ride_filter_metadata")
    def get(self, request):
        """Get ride filter metadata."""
        try:
            # Check if metadata should be scoped to current filters
            scoped = request.query_params.get("scoped", "").lower() == "true"
            filters = None

            if scoped:
                filters = self._extract_filters(request.query_params)

            # Get filter metadata
            metadata = smart_ride_loader.get_filter_metadata(filters)

            return Response(metadata, status=status.HTTP_200_OK)

        except Exception as e:
            capture_and_log(e, 'Get ride filter metadata', source='api')
            return Response(
                {"detail": "Internal server error"},
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            )

    def _extract_filters(self, query_params):
        """Extract and parse filters from query parameters."""
        # Reuse the same filter extraction logic
        view = HybridRideAPIView()
        return view._extract_filters(query_params)


# === MANUFACTURER & DESIGNER LISTS ===


class BaseCompanyListAPIView(APIView):
    permission_classes = [permissions.AllowAny]
    role = None

    def get(self, request: Request) -> Response:
        if not MODELS_AVAILABLE:
            return Response({"detail": "Models not available"}, status=status.HTTP_501_NOT_IMPLEMENTED)

        companies = (
            Company.objects.filter(roles__contains=[self.role])
            .annotate(ride_count=Count("manufactured_rides" if self.role == "MANUFACTURER" else "designed_rides"))
            .only("id", "name", "slug", "roles", "description")
            .order_by("name")
        )

        data = [
            {
                "id": c.id,
                "name": c.name,
                "slug": c.slug,
                "description": c.description,
                "ride_count": c.ride_count,
            }
            for c in companies
        ]

        return Response({"results": data, "count": len(data)})


@extend_schema(
    summary="List manufacturers",
    description="List all companies with MANUFACTURER role.",
    responses={200: OpenApiTypes.OBJECT},
    tags=["Rides"],
)
class ManufacturerListAPIView(BaseCompanyListAPIView):
    role = "MANUFACTURER"


@extend_schema(
    summary="List designers",
    description="List all companies with DESIGNER role.",
    responses={200: OpenApiTypes.OBJECT},
    tags=["Rides"],
)
class DesignerListAPIView(BaseCompanyListAPIView):
    role = "DESIGNER"
