""" Serializers for ride review API endpoints. This module contains serializers for ride review CRUD operations with Rich Choice Objects compliance. """ from rest_framework import serializers from drf_spectacular.utils import extend_schema_field, extend_schema_serializer, OpenApiExample from apps.rides.models.reviews import RideReview from apps.accounts.models import User from apps.core.choices.serializers import RichChoiceSerializer class ReviewUserSerializer(serializers.ModelSerializer): """Serializer for user information in ride reviews.""" avatar_url = serializers.SerializerMethodField() display_name = serializers.SerializerMethodField() class Meta: model = User fields = ["id", "username", "display_name", "avatar_url"] read_only_fields = fields @extend_schema_field(serializers.URLField(allow_null=True)) def get_avatar_url(self, obj): """Get the user's avatar URL.""" if hasattr(obj, "profile") and obj.profile: return obj.profile.get_avatar_url() return "/static/images/default-avatar.png" @extend_schema_field(serializers.CharField()) def get_display_name(self, obj): """Get the user's display name.""" return obj.get_display_name() @extend_schema_serializer( examples=[ OpenApiExample( name="Complete Ride Review", summary="Full ride review response", description="Example response showing all fields for a ride review", value={ "id": 123, "title": "Amazing roller coaster experience!", "content": "This ride was absolutely incredible. The inversions were smooth and the theming was top-notch.", "rating": 9, "visit_date": "2023-06-15", "created_at": "2023-06-16T10:30:00Z", "updated_at": "2023-06-16T10:30:00Z", "is_published": True, "user": { "id": 456, "username": "coaster_fan", "display_name": "Coaster Fan", "avatar_url": "https://example.com/avatar.jpg" }, "ride": { "id": 789, "name": "Steel Vengeance", "slug": "steel-vengeance" }, "park": { "id": 101, "name": "Cedar Point", "slug": "cedar-point" } } ) ] ) class RideReviewOutputSerializer(serializers.ModelSerializer): """Output serializer for ride reviews.""" user = ReviewUserSerializer(read_only=True) # Ride information ride = serializers.SerializerMethodField() park = serializers.SerializerMethodField() class Meta: model = RideReview fields = [ "id", "title", "content", "rating", "visit_date", "created_at", "updated_at", "is_published", "user", "ride", "park", ] read_only_fields = [ "id", "created_at", "updated_at", "user", "ride", "park", ] @extend_schema_field(serializers.DictField()) def get_ride(self, obj): """Get ride information.""" return { "id": obj.ride.id, "name": obj.ride.name, "slug": obj.ride.slug, } @extend_schema_field(serializers.DictField()) def get_park(self, obj): """Get park information.""" return { "id": obj.ride.park.id, "name": obj.ride.park.name, "slug": obj.ride.park.slug, } class RideReviewCreateInputSerializer(serializers.ModelSerializer): """Input serializer for creating ride reviews.""" class Meta: model = RideReview fields = [ "title", "content", "rating", "visit_date", ] def validate_rating(self, value): """Validate rating is between 1 and 10.""" if not (1 <= value <= 10): raise serializers.ValidationError("Rating must be between 1 and 10.") return value class RideReviewUpdateInputSerializer(serializers.ModelSerializer): """Input serializer for updating ride reviews.""" class Meta: model = RideReview fields = [ "title", "content", "rating", "visit_date", ] def validate_rating(self, value): """Validate rating is between 1 and 10.""" if not (1 <= value <= 10): raise serializers.ValidationError("Rating must be between 1 and 10.") return value class RideReviewListOutputSerializer(serializers.ModelSerializer): """Simplified output serializer for ride review lists.""" user = ReviewUserSerializer(read_only=True) ride_name = serializers.CharField(source="ride.name", read_only=True) park_name = serializers.CharField(source="ride.park.name", read_only=True) class Meta: model = RideReview fields = [ "id", "title", "rating", "visit_date", "created_at", "is_published", "user", "ride_name", "park_name", ] read_only_fields = fields class RideReviewStatsOutputSerializer(serializers.Serializer): """Output serializer for ride review statistics.""" total_reviews = serializers.IntegerField() published_reviews = serializers.IntegerField() pending_reviews = serializers.IntegerField() average_rating = serializers.FloatField(allow_null=True) rating_distribution = serializers.DictField( child=serializers.IntegerField(), help_text="Count of reviews by rating (1-10)" ) recent_reviews = serializers.IntegerField() class RideReviewModerationInputSerializer(serializers.Serializer): """Input serializer for review moderation operations.""" review_ids = serializers.ListField( child=serializers.IntegerField(), help_text="List of review IDs to moderate" ) action = serializers.ChoiceField( choices=[ ("publish", "Publish"), ("unpublish", "Unpublish"), ("delete", "Delete"), ], help_text="Moderation action to perform" ) moderation_notes = serializers.CharField( required=False, allow_blank=True, help_text="Optional notes about the moderation action" )