from rest_framework import permissions, serializers, status
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework.response import Response
from rest_framework.views import APIView

from shipment import models as shipment_models


def _get_employee(request):
    employee = getattr(request.user, 'employee', None)
    if employee is None:
        raise serializers.ValidationError('当前用户未关联员工')
    return employee


class ShipmentDeliveryPhotoWriteSerializer(serializers.ModelSerializer):
    shipment = serializers.PrimaryKeyRelatedField(queryset=shipment_models.Shipment.objects.all())
    delivery = serializers.PrimaryKeyRelatedField(queryset=shipment_models.ShipmentDelivery.objects.all())

    class Meta:
        model = shipment_models.ShipmentDeliveryPhoto
        fields = ['shipment', 'delivery', 'photo', 'remark']

    def validate(self, attrs):
        employee = self.context['employee']
        instance = self.instance
        shipment = attrs.get('shipment', getattr(instance, 'shipment', None))
        delivery = attrs.get('delivery', getattr(instance, 'delivery', None))

        if shipment is None:
            raise serializers.ValidationError({'shipment': '出货单不能为空'})
        if delivery is None:
            raise serializers.ValidationError({'delivery': '送货单不能为空'})
        if shipment.merchant_id != employee.merchant_id:
            raise serializers.ValidationError({'shipment': '出货单不属于当前商户'})
        if delivery.merchant_id != employee.merchant_id:
            raise serializers.ValidationError({'delivery': '送货单不属于当前商户'})
        if shipment.delivery_id != delivery.id:
            raise serializers.ValidationError({'delivery': '送货单与出货单当前绑定关系不一致'})
        return attrs


class ShipmentDeliveryPhotoReadSerializer(serializers.ModelSerializer):
    created_by = serializers.IntegerField(source='created_by_id', read_only=True, allow_null=True)
    shipment_id = serializers.IntegerField(read_only=True)
    delivery_id = serializers.IntegerField(read_only=True)

    class Meta:
        model = shipment_models.ShipmentDeliveryPhoto
        fields = [
            'id',
            'shipment_id',
            'delivery_id',
            'photo',
            'remark',
            'created_by',
            'created_at',
            'updated_at',
        ]
        read_only_fields = fields


class ShipmentDeliveryPhotoListCreateView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser]

    def _queryset(self, employee):
        return shipment_models.ShipmentDeliveryPhoto.objects.select_related(
            'shipment', 'delivery', 'created_by'
        ).filter(
            shipment__merchant=employee.merchant,
            delivery__merchant=employee.merchant,
        )

    def get(self, request):
        employee = _get_employee(request)
        queryset = self._queryset(employee)

        shipment_id = request.query_params.get('shipment_id')
        delivery_id = request.query_params.get('delivery_id')
        if shipment_id:
            queryset = queryset.filter(shipment_id=shipment_id)
        if delivery_id:
            queryset = queryset.filter(delivery_id=delivery_id)

        return Response(ShipmentDeliveryPhotoReadSerializer(queryset, many=True, context={'request': request}).data)

    def post(self, request):
        employee = _get_employee(request)
        serializer = ShipmentDeliveryPhotoWriteSerializer(data=request.data, context={'employee': employee})
        serializer.is_valid(raise_exception=True)
        photo = serializer.save(created_by=request.user)
        return Response(
            ShipmentDeliveryPhotoReadSerializer(photo, context={'request': request}).data,
            status=status.HTTP_201_CREATED,
        )


class ShipmentDeliveryPhotoDetailView(APIView):
    permission_classes = [permissions.IsAuthenticated]
    parser_classes = [MultiPartParser, FormParser]

    def get_object(self, request, photo_id):
        employee = _get_employee(request)
        return shipment_models.ShipmentDeliveryPhoto.objects.select_related(
            'shipment', 'delivery', 'created_by'
        ).filter(
            shipment__merchant=employee.merchant,
            delivery__merchant=employee.merchant,
            id=photo_id,
        ).first()

    def get(self, request, photo_id):
        photo = self.get_object(request, photo_id)
        if photo is None:
            return Response({'detail': '未找到送达照片'}, status=status.HTTP_404_NOT_FOUND)
        return Response(ShipmentDeliveryPhotoReadSerializer(photo, context={'request': request}).data)

    def patch(self, request, photo_id):
        photo = self.get_object(request, photo_id)
        if photo is None:
            return Response({'detail': '未找到送达照片'}, status=status.HTTP_404_NOT_FOUND)
        employee = _get_employee(request)
        serializer = ShipmentDeliveryPhotoWriteSerializer(photo, data=request.data, partial=True, context={'employee': employee})
        serializer.is_valid(raise_exception=True)
        photo = serializer.save()
        return Response(ShipmentDeliveryPhotoReadSerializer(photo, context={'request': request}).data)

    def put(self, request, photo_id):
        photo = self.get_object(request, photo_id)
        if photo is None:
            return Response({'detail': '未找到送达照片'}, status=status.HTTP_404_NOT_FOUND)
        employee = _get_employee(request)
        serializer = ShipmentDeliveryPhotoWriteSerializer(photo, data=request.data, context={'employee': employee})
        serializer.is_valid(raise_exception=True)
        photo = serializer.save()
        return Response(ShipmentDeliveryPhotoReadSerializer(photo, context={'request': request}).data)

    def delete(self, request, photo_id):
        photo = self.get_object(request, photo_id)
        if photo is None:
            return Response({'detail': '未找到送达照片'}, status=status.HTTP_404_NOT_FOUND)
        photo.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)