from rest_framework import status
from rest_framework.parsers import MultiPartParser
from rest_framework.permissions import AllowAny
from rest_framework.response import Response

from apps.station import models as station_model
from apps.station.filters.station_filters import SuggestStationListFilter
from apps.station.serializers import station_request_report_serializers
from apps.station.services import station_services
from base.permissions import AdminOrPostOnlyPermission
from base.views import BaseModelViewSet


class StationEditRequestMediaModelViewSet(BaseModelViewSet):
    """
    This is the StationEditRequestMediaModelViewSet class responsible for managing station media assets,
    such as images or files.

    It provides endpoints for uploading and deleting media assets associated with station records.

    Attributes:
        permission_classes (tuple): Specifies the permissions required to access this view. It's set to IsAuthenticated,
        allowing only authenticated users to use this view.
        parser_classes (tuple): The parsers used for request data, which includes MultiPartParser for
        handling file uploads.
        serializer_class (UploadStationMediaSerializer): The serializer class used for
        deserializing and handling media asset data.
        queryset (QuerySet): The queryset for accessing station media records.
        http_method_names (list): Specifies the supported HTTP methods for this view, including 'post' and 'delete'.

    Methods:
        create(request, *args, **kwargs): Handles the uploading of station media assets and
        associates them with a specific station.
    """

    parser_classes = (MultiPartParser,)
    serializer_class = (
        station_request_report_serializers.StationEditRequestMediaSerializer
    )
    queryset = station_model.SuggestStationMedia.objects.all()
    http_method_names = ["post"]

    def create(self, request, *args, **kwargs):
        """
        Handles the uploading of station media assets and associates them with a specific station.

        Args:
            request (HttpRequest): The HTTP request object containing media assets and associated data.
            *args: Variable-length argument list.
            **kwargs: Arbitrary keyword arguments.

        Returns:
            Response: A response indicating the success or failure of the media asset upload operation.

        This method processes the uploaded media assets, associates them with a specified station, and handles the creation
        of station media records. It verifies the provided station ID, asset data, and the associated user.
        """

        station_id = self.kwargs.get("station_id")
        station = station_services.get_suggest_station(station_id)

        if not station:
            return Response(
                {"message": "Invalid station ID"},
                status=status.HTTP_400_BAD_REQUEST,
            )

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

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

        serializer = (
            station_request_report_serializers.StationEditRequestMediaSerializer(
                data=assets, many=True
            )
        )

        if serializer.is_valid():
            serializer.save(suggest_station=station, user=request.user)
            return Response(
                {"detail": "Station media uploaded successfully."},
                status=status.HTTP_201_CREATED,
            )
        else:
            return Response(
                serializer.errors,
                status=status.HTTP_400_BAD_REQUEST,
            )


class StationEditRequestModelViewSet(BaseModelViewSet):
    """
    This is the StationEditRequestModelViewSet class responsible for handling CSV file uploads for station data.

    It provides endpoints for uploading and updating station data from CSV files.

    Attributes:
        permission_classes (tuple): Specifies the permissions required to access this view. It's set to IsAuthenticated,
                                   allowing only authenticated users to use this view.
    """

    permission_classes = (AdminOrPostOnlyPermission,)
    serializer_class = station_request_report_serializers.StationEditRequestSerializer
    queryset = station_model.SuggestStation.objects.all()
    filterset_class = SuggestStationListFilter
    http_method_names = ["post", "patch", "get"]

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

        Args:
            serializer (StationEditRequestSerializer): The serializer for creating a new station data record.

        This method associates the created station data record with the requesting user.
        """
        serializer.save(user=self.request.user)


class StationReportReasonModelViewSet(BaseModelViewSet):
    """
    This is the StationReportReasonModelViewSet class responsible for providing station report reasons.

    It provides endpoints to retrieve reasons for station reports, allowing public access.

    Attributes:
        permission_classes (tuple): Specifies the permissions required to access this view. It's set to AllowAny,
                                   allowing public access to retrieve station report reasons.
    """

    permission_classes = (AllowAny,)
    serializer_class = station_request_report_serializers.StationReportReasonSerializer
    queryset = station_model.StationReasonMaster.objects.all()
    http_method_names = ["get"]


class StationReportModelViewSet(BaseModelViewSet):
    """
    This is the StationReportModelViewSet class responsible for handling station report submissions.

    It provides endpoints for authenticated users to submit station reports.

    Attributes:
        permission_classes (tuple): Specifies the permissions required to access this view. It's set to IsAuthenticated,
                                   allowing only authenticated users to use this view.

    Methods:
        perform_create(serializer): Associates the created station data record with the requesting user.
    """

    serializer_class = station_request_report_serializers.StationReportSerializer
    queryset = station_model.StationReport.objects.all()
    http_method_names = ["post"]

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

        Args:
        serializer (StationReportSerializer): The serializer for creating a new station data record.

        This method associates the created station data record with the requesting user.
        """
        serializer.save(user=self.request.user)
