"""
Global Ride Model views for ThrillWiki API v1.

This module provides top-level ride model endpoints that don't require
manufacturer context, matching the frontend's expectation of /rides/models/.
"""

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

# Import serializers
from apps.api.v1.serializers.ride_models import (
    RideModelDetailOutputSerializer,
    RideModelListOutputSerializer,
)

# Attempt to import models
try:
    from apps.rides.models import RideModel
    from apps.rides.models.company import Company

    MODELS_AVAILABLE = True
except ImportError:
    try:
        from apps.rides.models.rides import Company, RideModel

        MODELS_AVAILABLE = True
    except ImportError:
        RideModel = None
        Company = None
        MODELS_AVAILABLE = False


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


class GlobalRideModelListAPIView(APIView):
    """
    Global ride model list endpoint.
    
    This endpoint provides a top-level list of all ride models without
    requiring a manufacturer slug, matching the frontend's expectation
    of calling /rides/models/ directly.
    """
    
    permission_classes = [permissions.AllowAny]

    @extend_schema(
        summary="List all ride models with filtering and pagination",
        description=(
            "List all ride models across all manufacturers with comprehensive "
            "filtering and pagination support. This is a global endpoint that "
            "doesn't require manufacturer context."
        ),
        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 100)",
            ),
            OpenApiParameter(
                name="search",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Search term for name, description, or manufacturer",
            ),
            OpenApiParameter(
                name="category",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by category (e.g., RC, DR, FR, WR)",
            ),
            OpenApiParameter(
                name="manufacturer",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by manufacturer slug",
            ),
            OpenApiParameter(
                name="target_market",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Filter by target market (e.g., FAMILY, THRILL)",
            ),
            OpenApiParameter(
                name="is_discontinued",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.BOOL,
                description="Filter by discontinued status",
            ),
            OpenApiParameter(
                name="ordering",
                location=OpenApiParameter.QUERY,
                type=OpenApiTypes.STR,
                description="Order by field: name, -name, manufacturer__name, etc.",
            ),
        ],
        responses={200: RideModelListOutputSerializer(many=True)},
        tags=["Ride Models"],
    )
    def get(self, request: Request) -> Response:
        """List all ride models with filtering and pagination."""
        if not MODELS_AVAILABLE:
            return Response(
                {
                    "count": 0,
                    "next": None,
                    "previous": None,
                    "results": [],
                    "detail": "Ride model listing is not available.",
                },
                status=status.HTTP_200_OK,
            )

        # Base queryset with eager loading
        qs = RideModel.objects.select_related("manufacturer").prefetch_related(
            "photos"
        ).order_by("manufacturer__name", "name")

        # Search filter
        search = request.query_params.get("search", "").strip()
        if search:
            qs = qs.filter(
                Q(name__icontains=search)
                | Q(description__icontains=search)
                | Q(manufacturer__name__icontains=search)
            )

        # Category filter
        category = request.query_params.get("category", "").strip()
        if category:
            # Support comma-separated categories
            categories = [c.strip() for c in category.split(",") if c.strip()]
            if categories:
                qs = qs.filter(category__in=categories)

        # Manufacturer filter
        manufacturer = request.query_params.get("manufacturer", "").strip()
        if manufacturer:
            qs = qs.filter(manufacturer__slug=manufacturer)

        # Target market filter
        target_market = request.query_params.get("target_market", "").strip()
        if target_market:
            markets = [m.strip() for m in target_market.split(",") if m.strip()]
            if markets:
                qs = qs.filter(target_market__in=markets)

        # Discontinued filter
        is_discontinued = request.query_params.get("is_discontinued")
        if is_discontinued is not None:
            qs = qs.filter(is_discontinued=is_discontinued.lower() == "true")

        # Ordering
        ordering = request.query_params.get("ordering", "manufacturer__name,name")
        valid_orderings = [
            "name", "-name",
            "manufacturer__name", "-manufacturer__name",
            "first_installation_year", "-first_installation_year",
            "total_installations", "-total_installations",
            "created_at", "-created_at",
        ]
        if ordering:
            order_fields = [
                f.strip() for f in ordering.split(",")
                if f.strip() in valid_orderings or f.strip().lstrip("-") in [
                    o.lstrip("-") for o in valid_orderings
                ]
            ]
            if order_fields:
                qs = qs.order_by(*order_fields)

        # Paginate
        paginator = StandardResultsSetPagination()
        page = paginator.paginate_queryset(qs, request)
        
        if page is not None:
            serializer = RideModelListOutputSerializer(
                page, many=True, context={"request": request}
            )
            return paginator.get_paginated_response(serializer.data)

        # Fallback without pagination
        serializer = RideModelListOutputSerializer(
            qs[:100], many=True, context={"request": request}
        )
        return Response(serializer.data)


class GlobalRideModelDetailAPIView(APIView):
    """
    Global ride model detail endpoint by ID or slug.
    
    This endpoint provides detail for a single ride model without
    requiring manufacturer context.
    """
    
    permission_classes = [permissions.AllowAny]

    @extend_schema(
        summary="Retrieve a ride model by ID",
        description="Get detailed information about a specific ride model by its ID.",
        parameters=[
            OpenApiParameter(
                name="pk",
                location=OpenApiParameter.PATH,
                type=OpenApiTypes.INT,
                required=True,
                description="Ride model ID",
            ),
        ],
        responses={200: RideModelDetailOutputSerializer()},
        tags=["Ride Models"],
    )
    def get(self, request: Request, pk: int) -> Response:
        """Get ride model detail by ID."""
        if not MODELS_AVAILABLE:
            return Response(
                {"detail": "Ride model not found"},
                status=status.HTTP_404_NOT_FOUND,
            )

        try:
            ride_model = (
                RideModel.objects.select_related("manufacturer")
                .prefetch_related("photos", "variants", "technical_specs")
                .get(pk=pk)
            )
        except RideModel.DoesNotExist:
            return Response(
                {"detail": "Ride model not found"},
                status=status.HTTP_404_NOT_FOUND,
            )

        serializer = RideModelDetailOutputSerializer(
            ride_model, context={"request": request}
        )
        return Response(serializer.data)
