"""
Ride Model endpoints for API v1.

Provides CRUD operations for RideModel entities with filtering and search.
"""
from typing import List, Optional
from uuid import UUID
from django.shortcuts import get_object_or_404
from django.db.models import Q
from ninja import Router, Query
from ninja.pagination import paginate, PageNumberPagination

from apps.entities.models import RideModel, Company
from ..schemas import (
    RideModelCreate,
    RideModelUpdate,
    RideModelOut,
    RideModelListOut,
    ErrorResponse
)


router = Router(tags=["Ride Models"])


class RideModelPagination(PageNumberPagination):
    """Custom pagination for ride models."""
    page_size = 50


@router.get(
    "/",
    response={200: List[RideModelOut]},
    summary="List ride models",
    description="Get a paginated list of ride models with optional filtering"
)
@paginate(RideModelPagination)
def list_ride_models(
    request,
    search: Optional[str] = Query(None, description="Search by model name"),
    manufacturer_id: Optional[UUID] = Query(None, description="Filter by manufacturer"),
    model_type: Optional[str] = Query(None, description="Filter by model type"),
    ordering: Optional[str] = Query("-created", description="Sort by field (prefix with - for descending)")
):
    """
    List all ride models with optional filters.
    
    **Filters:**
    - search: Search model names (case-insensitive partial match)
    - manufacturer_id: Filter by manufacturer
    - model_type: Filter by model type
    - ordering: Sort results (default: -created)
    
    **Returns:** Paginated list of ride models
    """
    queryset = RideModel.objects.select_related('manufacturer').all()
    
    # Apply search filter
    if search:
        queryset = queryset.filter(
            Q(name__icontains=search) | Q(description__icontains=search)
        )
    
    # Apply manufacturer filter
    if manufacturer_id:
        queryset = queryset.filter(manufacturer_id=manufacturer_id)
    
    # Apply model type filter
    if model_type:
        queryset = queryset.filter(model_type=model_type)
    
    # Apply ordering
    valid_order_fields = ['name', 'created', 'modified', 'installation_count']
    order_field = ordering.lstrip('-')
    if order_field in valid_order_fields:
        queryset = queryset.order_by(ordering)
    else:
        queryset = queryset.order_by('-created')
    
    # Annotate with manufacturer name
    for model in queryset:
        model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
    
    return queryset


@router.get(
    "/{model_id}",
    response={200: RideModelOut, 404: ErrorResponse},
    summary="Get ride model",
    description="Retrieve a single ride model by ID"
)
def get_ride_model(request, model_id: UUID):
    """
    Get a ride model by ID.
    
    **Parameters:**
    - model_id: UUID of the ride model
    
    **Returns:** Ride model details
    """
    model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
    model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
    return model


@router.post(
    "/",
    response={201: RideModelOut, 400: ErrorResponse, 404: ErrorResponse},
    summary="Create ride model",
    description="Create a new ride model (requires authentication)"
)
def create_ride_model(request, payload: RideModelCreate):
    """
    Create a new ride model.
    
    **Authentication:** Required
    
    **Parameters:**
    - payload: Ride model data
    
    **Returns:** Created ride model
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    # Verify manufacturer exists
    manufacturer = get_object_or_404(Company, id=payload.manufacturer_id)
    
    model = RideModel.objects.create(**payload.dict())
    model.manufacturer_name = manufacturer.name
    return 201, model


@router.put(
    "/{model_id}",
    response={200: RideModelOut, 404: ErrorResponse, 400: ErrorResponse},
    summary="Update ride model",
    description="Update an existing ride model (requires authentication)"
)
def update_ride_model(request, model_id: UUID, payload: RideModelUpdate):
    """
    Update a ride model.
    
    **Authentication:** Required
    
    **Parameters:**
    - model_id: UUID of the ride model
    - payload: Updated ride model data
    
    **Returns:** Updated ride model
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
    
    # Update only provided fields
    for key, value in payload.dict(exclude_unset=True).items():
        setattr(model, key, value)
    
    model.save()
    model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
    return model


@router.patch(
    "/{model_id}",
    response={200: RideModelOut, 404: ErrorResponse, 400: ErrorResponse},
    summary="Partial update ride model",
    description="Partially update an existing ride model (requires authentication)"
)
def partial_update_ride_model(request, model_id: UUID, payload: RideModelUpdate):
    """
    Partially update a ride model.
    
    **Authentication:** Required
    
    **Parameters:**
    - model_id: UUID of the ride model
    - payload: Fields to update
    
    **Returns:** Updated ride model
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    model = get_object_or_404(RideModel.objects.select_related('manufacturer'), id=model_id)
    
    # Update only provided fields
    for key, value in payload.dict(exclude_unset=True).items():
        setattr(model, key, value)
    
    model.save()
    model.manufacturer_name = model.manufacturer.name if model.manufacturer else None
    return model


@router.delete(
    "/{model_id}",
    response={204: None, 404: ErrorResponse},
    summary="Delete ride model",
    description="Delete a ride model (requires authentication)"
)
def delete_ride_model(request, model_id: UUID):
    """
    Delete a ride model.
    
    **Authentication:** Required
    
    **Parameters:**
    - model_id: UUID of the ride model
    
    **Returns:** No content (204)
    """
    # TODO: Add authentication check
    # if not request.auth:
    #     return 401, {"detail": "Authentication required"}
    
    model = get_object_or_404(RideModel, id=model_id)
    model.delete()
    return 204, None


@router.get(
    "/{model_id}/installations",
    response={200: List[dict], 404: ErrorResponse},
    summary="Get ride model installations",
    description="Get all ride installations of this model"
)
def get_ride_model_installations(request, model_id: UUID):
    """
    Get all installations of a ride model.
    
    **Parameters:**
    - model_id: UUID of the ride model
    
    **Returns:** List of rides using this model
    """
    model = get_object_or_404(RideModel, id=model_id)
    rides = model.rides.select_related('park').all().values(
        'id', 'name', 'slug', 'status', 'park__name', 'park__id'
    )
    return list(rides)
