"""
Views for review-related API endpoints.
"""

from itertools import chain
from operator import attrgetter

from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema
from rest_framework import status
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.parks.models.reviews import ParkReview
from apps.rides.models.reviews import RideReview

from ..serializers.reviews import LatestReviewSerializer


class LatestReviewsAPIView(APIView):
    """
    API endpoint to get the latest reviews from both parks and rides.

    Returns a combined list of the most recent reviews across the platform,
    including username, user avatar, date, score, and review snippet.
    """

    permission_classes = [AllowAny]

    @extend_schema(
        summary="Get Latest Reviews",
        description=(
            "Retrieve the latest reviews from both parks and rides. "
            "Returns a combined list sorted by creation date, including "
            "user information, ratings, and content snippets."
        ),
        parameters=[
            OpenApiParameter(
                name="limit",
                type=OpenApiTypes.INT,
                location=OpenApiParameter.QUERY,
                description="Number of reviews to return (default: 20, max: 100)",
                default=20,
            ),
        ],
        responses={
            200: LatestReviewSerializer(many=True),
        },
        tags=["Reviews"],
    )
    def get(self, request):
        """Get the latest reviews from both parks and rides."""
        # Get limit parameter with validation
        try:
            limit = int(request.query_params.get("limit", 20))
            limit = min(max(limit, 1), 100)  # Clamp between 1 and 100
        except (ValueError, TypeError):
            limit = 20

        # Get published reviews from both models
        park_reviews = (
            ParkReview.objects.filter(is_published=True)
            .select_related("user", "user__profile", "park")
            .order_by("-created_at")[:limit]
        )

        ride_reviews = (
            RideReview.objects.filter(is_published=True)
            .select_related("user", "user__profile", "ride", "ride__park")
            .order_by("-created_at")[:limit]
        )

        # Combine and sort by created_at
        all_reviews = sorted(
            chain(park_reviews, ride_reviews),
            key=attrgetter("created_at"),
            reverse=True,
        )[:limit]

        # Serialize the combined results
        serializer = LatestReviewSerializer(all_reviews, many=True)

        return Response(
            {"count": len(all_reviews), "results": serializer.data},
            status=status.HTTP_200_OK,
        )
