"""
Shipment API ViewSet
"""

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin

from flower.viewsets import LimitedLimitOffsetPagination
from shipment.models import Shipment

from .serializers import (
    SalesItemSerializer,
    ShipmentSerializer,
    ShipmentCreateNormalSerializer,
    ShipmentCreateExternalSerializer,
    ShipmentUpdateSerializer,
)


class ShipmentListCreateView(ListModelMixin, GenericAPIView):
    """
    出货单：查询列表 / 创建

    - GET /api/v1/shipment/shipments/
    - POST /api/v1/shipment/shipments/

    请求体:
    {
        "customer": 1,
        "shipment_date": "2026-01-14",
        "remark": "备注信息（可选）",
        "sales_items": [1, 2, 3]
    }

    返回:
    {
        "id": 1,
        "customer": 1,
        "customer_name": "客户A",
        "shipment_date": "2026-01-14",
        "remark": "备注信息",
        "items_count": 3,
        "created_by_id": 1,
        "created_by_name": "张三",
        "created_at": "2026-01-14T10:00:00Z",
        "updated_at": "2026-01-14T10:00:00Z"
    }
    """

    permission_classes = [IsAuthenticated]
    serializer_class = ShipmentSerializer
    pagination_class = LimitedLimitOffsetPagination

    def get_queryset(self):
        """
        仅返回当前用户所属商户的出货单（merchant 隔离）。

        支持过滤参数（可选）：
        - customer: 客户ID
        - status: 状态（1/2/3）
        - external_id: 外部订单号（精确匹配）
        - shipment_date_from: 出货日期起始（YYYY-MM-DD）
        - shipment_date_to: 出货日期结束（YYYY-MM-DD，包含整天）
        """
        qs = (
            Shipment.objects.all()
            .select_related("merchant", "customer", "created_by", "cancelled_by")
            .prefetch_related(
                "items",
                "external_finished_products",
            )
        )

        user = self.request.user
        if not getattr(user, "is_superuser", False):
            emp = getattr(user, "employee", None)
            merchant = getattr(emp, "merchant", None) if emp else None
            if not merchant:
                return Shipment.objects.none()
            qs = qs.filter(merchant=merchant)

        # optional filters
        customer_id = self.request.query_params.get("customer")
        if customer_id:
            qs = qs.filter(customer_id=customer_id)

        status_val = self.request.query_params.get("status")
        if status_val:
            qs = qs.filter(status=status_val)

        external_id = self.request.query_params.get("external_id")
        if external_id:
            qs = qs.filter(external_id=external_id)

        date_from = self.request.query_params.get("shipment_date_from")
        if date_from:
            qs = qs.filter(shipment_date__gte=date_from)

        date_to = self.request.query_params.get("shipment_date_to")
        if date_to:
            # 通过 <= 过滤日期
            qs = qs.filter(shipment_date__lte=date_to)

        return qs.order_by("-created_at", "-id")

    def get(self, request):
        return self.list(request)

    def post(self, request):
        # 验证请求数据
        serializer = ShipmentCreateNormalSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        data = serializer.validated_data

        # 调用业务逻辑
        from shipment.services import create_shipment

        try:
            shipment = create_shipment(
                customer_id=data["customer"],
                shipment_date=data["shipment_date"],
                sales_item_ids=data["sales_items"],
                created_by=request.user,
                remark=data.get("remark", ""),
                area=data.get("area", ""),
            )
        except ValueError as e:
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)

        # 返回创建的出货单
        response_serializer = ShipmentSerializer(shipment)
        return Response(response_serializer.data, status=status.HTTP_201_CREATED)


class ShipmentDetailView(RetrieveModelMixin, GenericAPIView):
    """
    出货单详情

    GET /api/v1/shipment/shipments/<id>/
    """

    permission_classes = [IsAuthenticated]
    serializer_class = ShipmentSerializer

    def get_queryset(self):
        qs = (
            Shipment.objects.all()
            .select_related("merchant", "customer", "created_by", "cancelled_by")
            .prefetch_related(
                "items",
                "external_finished_products",
            )
        )

        user = self.request.user
        if getattr(user, "is_superuser", False):
            return qs

        emp = getattr(user, "employee", None)
        merchant = getattr(emp, "merchant", None) if emp else None
        if not merchant:
            return Shipment.objects.none()
        return qs.filter(merchant=merchant)

    def get(self, request, pk: int):
        return self.retrieve(request, pk=pk)

    def patch(self, request, pk: int):
        """
        更新出货单（部分更新）
        PATCH /api/v1/shipment/shipments/<id>/
        """
        shipment = self.get_object()
        serializer = ShipmentUpdateSerializer(data=request.data, partial=True)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        data = serializer.validated_data

        # customer 变更需校验 merchant 一致
        if "customer" in data:
            from basic_info.models import Customer

            try:
                customer = Customer.objects.get(id=data["customer"])
            except Customer.DoesNotExist:
                return Response(
                    {"detail": f"客户 {data['customer']} 不存在"},
                    status=status.HTTP_400_BAD_REQUEST,
                )
            if customer.merchant_id != shipment.merchant_id:
                return Response(
                    {"detail": "无权限绑定该客户"}, status=status.HTTP_400_BAD_REQUEST
                )
            shipment.customer = customer

        if "shipment_date" in data:
            shipment.shipment_date = data["shipment_date"]
        if "area" in data:
            shipment.area = (data.get("area") or "").strip()
        if "remark" in data:
            shipment.remark = data.get("remark") or ""
        if "external_id" in data:
            shipment.external_id = (data.get("external_id") or "").strip() or None

        shipment.save()
        return Response(ShipmentSerializer(shipment).data, status=status.HTTP_200_OK)

    def put(self, request, pk: int):
        """
        更新出货单（全量更新，当前实现允许缺省字段，等同于 PATCH）
        PUT /api/v1/shipment/shipments/<id>/
        """
        return self.patch(request, pk=pk)


class ShipmentExternalCreateView(APIView):
    """
    创建出货单（external 版）

    POST /api/v1/shipment/shipments/external/

    特点：
    - external_id 必填
    - external_finished_products 必填（数组）
    - 不绑定任何销售品
    """

    permission_classes = [IsAuthenticated]

    def post(self, request):
        serializer = ShipmentCreateExternalSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        data = serializer.validated_data

        from shipment.services import create_external_shipment

        try:
            shipment = create_external_shipment(
                customer_id=data["customer"],
                shipment_date=data["shipment_date"],
                external_id=data["external_id"],
                external_finished_products=data["external_finished_products"],
                created_by=request.user,
                remark=data.get("remark", ""),
                area=data.get("area", ""),
            )
        except ValueError as e:
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)

        response_serializer = ShipmentSerializer(shipment)
        return Response(response_serializer.data, status=status.HTTP_201_CREATED)


class SalesItemByPrintingOrderView(APIView):
    """
    通过生产订单查询销售品

    GET /api/v1/shipment/sales-items/by-printing-order/<printing_order_id>/

    返回与该 PrintingOrder 下所有 PrintingJob 关联的 SalesItem 列表。

    查询参数:
    - include_already_has_shipment: 是否包含已关联出货单的销售品（true/false），默认 false

    返回:
    {
        "count": 5,
        "results": [
            {
                "id": 1,
                "name": "产品A",
                "quantity": "100.00",
                "unit": 1,
                "unit_display": "米",
                "position": "A1-01",
                "remark": "",
                "printing_job_id": 123,
                "customer_id": null,
                "shipment_id": null,
                "shipment_date": null,
                "created_at": "2026-01-14T10:00:00Z",
                "created_by_id": 1,
                "created_by_name": "张三"
            },
            ...
        ]
    }
    """

    permission_classes = [IsAuthenticated]

    def get(self, request, printing_order_id):
        # 验证生产订单是否存在
        from printing.models import PrintingOrder

        try:
            printing_order = PrintingOrder.objects.get(id=printing_order_id)
        except PrintingOrder.DoesNotExist:
            return Response(
                {"detail": f"生产订单 {printing_order_id} 不存在"},
                status=status.HTTP_404_NOT_FOUND,
            )

        # 获取查询参数
        include_already_has_shipment = (
            request.query_params.get("include_already_has_shipment", "false").lower()
            == "true"
        )

        # 调用 shipment 业务逻辑
        from shipment.services import get_sales_items_by_printing_order

        sales_items = get_sales_items_by_printing_order(
            printing_order_id=printing_order.id,
            include_already_has_shipment=include_already_has_shipment,
        )

        # 序列化返回
        serializer = SalesItemSerializer(sales_items, many=True)

        return Response({"count": len(serializer.data), "results": serializer.data})


class SalesItemCreateView(APIView):
    """
    手动创建销售品

    POST /api/v1/shipment/sales-items/

    当自动转化销售品开关关闭时，通过此接口手动创建销售品。

    请求体:
    {
        "printing_job_id": 123,
        "name": "产品名称",
        "quantity": "100.50",
        "unit": 1,
        "customer_id": 456,
        "remark": "备注信息",
        "position": "A1-01"
    }

    参数说明:
    - printing_job_id: 生产任务ID（必填）
    - name: 销售品名称（必填）
    - quantity: 数量（必填，支持小数）
    - unit: 单位（必填）：1=米, 2=件, 3=码, 4=个
    - customer_id: 客户ID（可选，默认从生产订单获取）
    - remark: 备注（可选）
    - position: 货位（可选）

    返回:
    {
        "id": 1,
        "name": "产品名称",
        "quantity": "100.50",
        "unit": 1,
        "unit_display": "米",
        "position": "A1-01",
        "remark": "备注信息",
        "printing_job_id": 123,
        "customer_id": 456,
        "shipment_id": null,
        "shipment_date": null,
        "created_at": "2026-01-14T10:00:00Z",
        "created_by_id": 1,
        "created_by_name": "张三"
    }
    """

    permission_classes = [IsAuthenticated]

    def post(self, request):
        from .serializers import SalesItemCreateSerializer

        serializer = SalesItemCreateSerializer(
            data=request.data, context={"request": request}
        )

        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        try:
            sales_item = serializer.save()
        except ValueError as e:
            return Response({"detail": str(e)}, status=status.HTTP_400_BAD_REQUEST)

        # 返回创建的销售品
        response_serializer = SalesItemSerializer(sales_item)
        return Response(response_serializer.data, status=status.HTTP_201_CREATED)
