""" Ride API views for ThrillWiki API v1. """ import logging from django.core.exceptions import PermissionDenied from drf_spectacular.utils import extend_schema_view, extend_schema from drf_spectacular.types import OpenApiTypes from rest_framework import status from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from apps.rides.models import RidePhoto from apps.rides.services import RideMediaService from ..media.serializers import ( PhotoUpdateInputSerializer, PhotoListOutputSerializer, ) from .serializers import RidePhotoSerializer logger = logging.getLogger(__name__) @extend_schema_view( list=extend_schema( summary="List ride photos", description="Retrieve a list of photos for a specific ride.", responses={200: PhotoListOutputSerializer(many=True)}, tags=["Rides"], ), retrieve=extend_schema( summary="Get ride photo details", description="Retrieve detailed information about a specific ride photo.", responses={ 200: RidePhotoSerializer, 404: OpenApiTypes.OBJECT, }, tags=["Rides"], ), update=extend_schema( summary="Update ride photo", description="Update ride photo information (caption, alt text, etc.)", request=PhotoUpdateInputSerializer, responses={ 200: RidePhotoSerializer, 400: OpenApiTypes.OBJECT, 403: OpenApiTypes.OBJECT, 404: OpenApiTypes.OBJECT, }, tags=["Rides"], ), destroy=extend_schema( summary="Delete ride photo", description="Delete a ride photo (only by owner or admin)", responses={ 204: None, 403: OpenApiTypes.OBJECT, 404: OpenApiTypes.OBJECT, }, tags=["Rides"], ), ) class RidePhotoViewSet(ModelViewSet): """ViewSet for managing ride photos.""" queryset = RidePhoto.objects.select_related("ride", "uploaded_by").all() permission_classes = [IsAuthenticated] lookup_field = "id" def get_serializer_class(self): """Return appropriate serializer based on action.""" if self.action == "list": return PhotoListOutputSerializer elif self.action in ["update", "partial_update"]: return PhotoUpdateInputSerializer return RidePhotoSerializer def perform_update(self, serializer): """Update photo with permission check.""" photo = self.get_object() if not ( self.request.user == photo.uploaded_by or self.request.user.has_perm("rides.change_ridephoto") ): raise PermissionDenied("You do not have permission to edit this photo.") serializer.save() def perform_destroy(self, instance): """Delete photo with permission check.""" if not ( self.request.user == instance.uploaded_by or self.request.user.has_perm("rides.delete_ridephoto") ): raise PermissionDenied("You do not have permission to delete this photo.") instance.delete() @action(detail=True, methods=["post"]) def set_primary(self, request, id=None): """Set this photo as the primary photo for its ride.""" photo = self.get_object() if not ( request.user == photo.uploaded_by or request.user.has_perm("rides.change_ridephoto") ): return Response( {"error": "You do not have permission to edit photos for this ride."}, status=status.HTTP_403_FORBIDDEN, ) try: RideMediaService.set_primary_photo(photo.ride, photo) return Response({"message": "Photo set as primary successfully."}) except Exception as e: logger.error(f"Error in set_primary_photo: {str(e)}", exc_info=True) return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)