from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from apps.station import models
from apps.station.serializers import station_bookmark_serializers
from base.views import BaseModelViewSet


class StationBookmarkModelViewSet(BaseModelViewSet):
    """
    This is the StationBookmarkModelViewSet class responsible for managing bookmarked stations.

    It provides endpoints for creating, retrieving, and removing bookmarked stations.

    Attributes:
        permission_classes (tuple): Specifies the permissions required to access this view
        (IsAuthenticated for authenticated users).
        serializer_class: The serializer class used for handling station bookmark data.
        queryset (QuerySet): The queryset for accessing bookmarked station records.
        http_method_names (list): Specifies the supported HTTP methods for this view,
        including 'post', 'get', and 'delete'.
    """

    serializer_class = station_bookmark_serializers.StationBookmarkSerializer
    queryset = models.BookmarkStation.objects.all()
    http_method_names = ["post", "get", "delete"]

    def get_queryset(self):
        """
        Get the queryset of bookmarked stations for the requesting user.

        This method filters bookmarked station records based on the requesting user.

        Returns:
            QuerySet: The filtered queryset of bookmarked stations.
        """
        return self.queryset.filter(user=self.request.user)

    def perform_create(self, serializer):
        """
        Create a new station bookmark and associate it with the requesting user.

        Args:
        serializer (StationBookmarkSerializer): The serializer for creating a new station bookmark.
        """
        serializer.save(user=self.request.user)

    def destroy(self, request, *args, **kwargs):
        """
        Remove a station from the user's bookmarks.

        Args:
        request (HttpRequest): The HTTP request object.
        *args: Variable-length argument list.
        **kwargs: Arbitrary keyword arguments.

        Returns:
            Response: A response indicating the success or failure of the station removal operation.
        """
        instance = self.get_object()

        # Check request user and bookmark user are same
        if request.user != instance.user:
            return Response(
                {"message": "You can't remove other user station"},
                status=status.HTTP_400_BAD_REQUEST,
            )
        self.perform_destroy(instance)

        return Response(
            {"message": "Station removed from bookmark successfully"},
            status=status.HTTP_204_NO_CONTENT,
        )


class DeleteBookmarkStationAPIView(APIView):
    """
    API view to delete a bookmarked station for the logged-in user.
    """

    permission_classes = (IsAuthenticated,)

    def delete(self, request, station_id, *args, **kwargs):
        """
        Remove a station from the user's bookmarks.

        Args:
            request (HttpRequest): The HTTP request object.
            station_id (int): The primary key of the associated station.
            *args: Variable-length argument list.
            **kwargs: Arbitrary keyword arguments.

        Returns:
            Response: A response indicating the success or failure of the station removal operation.
        """
        try:
            # Fetch the bookmarked station based on station_id and the requesting user
            bookmarked_station = models.BookmarkStation.objects.get(
                station_id=station_id, user=request.user
            )

            # Delete the bookmarked station
            bookmarked_station.delete()

            return Response(
                {"message": "Station removed from bookmarks successfully"},
                status=status.HTTP_204_NO_CONTENT,
            )
        except models.BookmarkStation.DoesNotExist:
            return Response(
                {"message": "Bookmark not found"},
                status=status.HTTP_404_NOT_FOUND,
            )
