from django.core.exceptions import ObjectDoesNotExist
from rest_framework import status
from rest_framework.parsers import MultiPartParser
from rest_framework.response import Response

from apps.account.filters import user_vehicle_filters
from apps.account.models import UserVehicle, UserVehicleAssets
from apps.account.serializers import user_vehicle_serializers
from base.views import BaseModelViewSet


class UserVehicleModelViewSet(BaseModelViewSet):
    """
    This view manages user vehicle records, allowing user profile retrieval and vehicle management.

    Attributes:
        permission_classes (tuple): Permissions required to access this view (IsAuthenticated for authenticated users).
        parser_classes (tuple): Parsers used for request data (MultiPartParser for file uploads).
        serializer_class (user_vehicle_serializers.UserVehicleSerializer): The serializer class for user vehicle data.
        queryset (QuerySet): The set of user vehicle records that this viewset operates on.
        http_method_names (list): The allowed HTTP methods (POST, PUT, GET, DELETE are allowed).

    Methods:
        list(request): Retrieves a list of user vehicles (Not allowed, returns an error response).
        retrieve(request): Retrieves a specific user's vehicle details with permission checks.
        destroy(request): Deletes a specific user's vehicle with permission checks.
    """

    serializer_class = user_vehicle_serializers.UserVehicleSerializer
    queryset = UserVehicle.objects.all()
    filterset_class = user_vehicle_filters.UserVehicleListFilter
    http_method_names = ["post", "put", "get", "delete"]

    def get_queryset(self):
        """
        Filter user vehicle records based on the requesting user.

        Returns:
        QuerySet: User vehicle records belonging to the requesting user.

        This method filters the queryset to retrieve user vehicle records specific to the requesting user.
        """
        return self.queryset.filter(user=self.request.user)

    def perform_create(self, serializer):
        """
        Perform user vehicle record creation, associating it with the requesting user.

        Args:
        serializer (UserVehicleSerializer): The serializer for creating a new user vehicle.

        This method associates the created user vehicle record with the requesting user.
        """

        serializer.save(user=self.request.user)

    def retrieve(self, request, *args, **kwargs):
        """
        Retrieve a specific user's vehicle details with permission checks.

        Args:
        request (HttpRequest): The HTTP request for retrieving a user's vehicle.

        Returns:
        Response: The user's vehicle details or an error response if permission is denied.

        This method retrieves the details of a specific user's vehicle, with permission checks to ensure
        that the requesting user has access to the requested vehicle.
        """

        instance = self.get_object()
        if instance.user != request.user:
            return Response(
                {"error": "You do not have permission to see other user vehicle"},
                status=status.HTTP_403_FORBIDDEN,
            )

        serializer = self.serializer_class(instance, context={"request": request})
        return Response(serializer.data)

    def destroy(self, request, *args, **kwargs):
        """
        Delete a specific user's vehicle with permission checks.

        Args:
        request (HttpRequest): The HTTP request for deleting a user's vehicle.

        Returns:
        Response: A success message or an error response if permission is denied.

        This method deletes a specific user's vehicle, with permission checks to ensure that the
        requesting user has the authority to delete the vehicle.
        """

        instance = self.get_object()

        # Check request user and post user are same
        if request.user != instance.user:
            return Response(
                {"message": "You can't delete other user vehicle"},
                status=400,
            )
        self.perform_destroy(instance)

        return Response(
            {"message": "Vehicle deleted successfully"},
            status=status.HTTP_204_NO_CONTENT,
        )


class UserVehicleAssetsModelViewSet(BaseModelViewSet):
    """
    A viewset for handling CRUD operations on UserVehicleAssets instances.

    This viewset supports the creation and deletion of UserVehicleAssets instances.
    It includes validation to ensure that users can only upload and delete their own
    vehicle media.

    Attributes:
        serializer_class: The serializer class for the UserVehicleAssets model.
        parser_classes (tuple): A tuple of parser classes, including MultiPartParser.
        queryset: The queryset containing all UserVehicleAssets instances.
        http_method_names (list): List of HTTP methods allowed on this viewset.
    """

    serializer_class = user_vehicle_serializers.UserVehicleAssetSerializer
    parser_classes = (MultiPartParser,)
    queryset = UserVehicleAssets.objects.all()
    http_method_names = ["post", "delete"]

    def create(self, request, *args, **kwargs):
        """
        Create UserVehicleAssets instances.

        Handles HTTP POST method to create UserVehicleAssets instances.
        Validates permissions to ensure users can only upload their own vehicle media.

        Returns:
            Response: The HTTP response indicating success or failure.
        """
        user_vehicle_id = self.kwargs.get("user_vehicle_id")

        try:
            user_vehicle = UserVehicle.objects.get(id=user_vehicle_id)
            if user_vehicle.user != self.request.user:
                return Response(
                    {
                        "message": "You do not have permission to upload other users' rating media."
                    },
                    status=status.HTTP_400_BAD_REQUEST,
                )
        except ObjectDoesNotExist:
            return Response(
                {"message": "User vehicle dose not exist"},
                status=status.HTTP_404_NOT_FOUND,
            )

        assets = []
        for index, file in enumerate(request.FILES):
            assets.append(
                {
                    "asset": request.FILES.get(f"asset[{index}]"),
                }
            )

        # Allow only up-to 5 media per vehicle
        if (user_vehicle.user_vehicle_assets.count() + len(assets)) > 5:
            return Response(
                {"message": "You can upload up-to 5 images"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        if not assets:
            return Response(
                {"message": "Assets are required"},
                status=status.HTTP_400_BAD_REQUEST,
            )

        serializer = self.get_serializer(data=assets, many=True)

        if serializer.is_valid():
            serializer.save(user_vehicle=user_vehicle)
            return Response(
                {"message": "Vehicle media uploaded successfully."},
                status=status.HTTP_201_CREATED,
            )
        else:
            return Response(
                serializer.errors,
                status=status.HTTP_400_BAD_REQUEST,
            )

    def destroy(self, request, *args, **kwargs):
        """
        Delete UserVehicleAssets instances.

        Handles HTTP DELETE method to delete UserVehicleAssets instances.
        Validates permissions to ensure users can only delete their own vehicle media.

        Returns:
            Response: The HTTP response indicating success or failure.
        """
        instance = self.get_object()
        # Check that both user are same
        if request.user != instance.user_vehicle.user:
            return Response(
                {"message": "You can't delete other user vehicle media"},
                status=400,
            )
        self.perform_destroy(instance)

        return Response(
            {"message": "Vehicle media deleted successfully"},
            status=status.HTTP_204_NO_CONTENT,
        )
