from rest_framework import viewsets, mixins, status
from rest_framework.decorators import action
from rest_framework.response import Response

from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiResponse

from .models import ZasilkovnaShipment, ZasilkovnaPacket
from .serializers import (
        ZasilkovnaShipmentSerializer,
        ZasilkovnaPacketSerializer,
        TrackingURLSerializer,
)


@extend_schema_view(
    list=extend_schema(
        tags=["Zásilkovna"],
        summary="List shipments",
        description="Returns a paginated list of Packeta (Zásilkovna) shipments.",
        responses={200: ZasilkovnaShipmentSerializer},
    ),
    retrieve=extend_schema(
        tags=["Zásilkovna"],
        summary="Retrieve a shipment",
        description="Returns detail for a single shipment.",
        responses={200: ZasilkovnaShipmentSerializer},
    ),
)
class ZasilkovnaShipmentViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = ZasilkovnaShipment.objects.all().order_by("-created_at")
    serializer_class = ZasilkovnaShipmentSerializer



@extend_schema_view(
    retrieve=extend_schema(
        tags=["Zásilkovna"],
        summary="Retrieve a packet",
        description="Returns detail for a single packet.",
        responses={200: ZasilkovnaPacketSerializer},
    )
)
class ZasilkovnaPacketViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = ZasilkovnaPacket.objects.all()
    serializer_class = ZasilkovnaPacketSerializer

    @extend_schema(
        tags=["Zásilkovna"],
        summary="Get public tracking URL",
        description=(
            "Returns the public Zásilkovna tracking URL derived from the packet's barcode."
        ),
        responses={200: OpenApiResponse(response=TrackingURLSerializer)},
    )
    @action(detail=True, methods=["get"], url_path="tracking-url")
    def tracking_url(self, request, pk=None):
        packet: ZasilkovnaPacket = self.get_object()
        data = {
            "barcode": packet.barcode,
            "tracking_url": packet.get_tracking_url(),
        }
        return Response(data)
    

    @extend_schema(
        tags=["Zásilkovna"],
        summary="Cancel packet",
        description=(
            "Cancels the packet through the Packeta API and updates its state to CANCELED. "
            "No request body is required."
        ),
        request=None,
        responses={200: OpenApiResponse(response=ZasilkovnaPacketSerializer)},
    )
    @action(detail=True, methods=["patch"], url_path="cancel")
    def cancel(self, request, pk=None):
            packet: ZasilkovnaPacket = self.get_object()
            packet.cancel_packet()
            serializer = self.get_serializer(packet)
            return Response(serializer.data, status=status.HTTP_200_OK)
