"""
SCM API Views — v1.

ویوهای REST API ماژول خرید و تدارکات.
"""
from uuid import uuid4

from django.utils import timezone
from rest_framework import viewsets, status, filters
from rest_framework.decorators import action
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend

from ...infrastructure.persistence.models import (
    VendorCategoryModel,
    VendorModel,
    VendorContactModel,
    VendorBankAccountModel,
    VendorAddressModel,
)
from ...infrastructure.persistence.models_extended import (
    PurchaseRequisitionModel,
    PurchaseRequisitionLineModel,
    RFQModel,
    RFQLineModel,
    RFQVendorResponseModel,
    RFQVendorResponseLineModel,
    PurchaseOrderModel,
    PurchaseOrderLineModel,
    GoodsReceiptModel,
    GoodsReceiptLineModel,
    PurchaseReturnModel,
    PurchaseReturnLineModel,
    VendorEvaluationModel,
    VendorEvaluationScoreModel,
    EvaluationCriteriaModel,
    EvaluationPeriodModel,
    VendorPriceListModel,
    VendorPriceListItemModel,
    PurchaseDiscountModel,
)
from .serializers import (
    # Vendor
    VendorCategorySerializer,
    VendorCategoryListSerializer,
    VendorSerializer,
    VendorListSerializer,
    VendorCreateSerializer,
    VendorBlockSerializer,
    VendorContactSerializer,
    VendorBankAccountSerializer,
    VendorAddressSerializer,
    # PR
    PRSerializer,
    PRListSerializer,
    PRCreateSerializer,
    PRRejectSerializer,
    # RFQ
    RFQSerializer,
    RFQListSerializer,
    RFQAwardSerializer,
    RFQVendorResponseSerializer,
    # PO
    POSerializer,
    POListSerializer,
    POCreateSerializer,
    PORejectSerializer,
    # GR
    GRSerializer,
    GRListSerializer,
    GRCreateSerializer,
    # Return
    ReturnSerializer,
    ReturnListSerializer,
    # Evaluation
    EvaluationSerializer,
    EvaluationListSerializer,
    EvaluationCriteriaSerializer,
    EvaluationPeriodSerializer,
    EvaluationScoreSerializer,
    # Price
    PriceListSerializer,
    PriceListListSerializer,
    PriceListItemSerializer,
    DiscountSerializer,
)
from .permissions import (
    CanManageVendors,
    CanManagePR,
    CanManageRFQ,
    CanManagePO,
    CanManageGR,
    CanManageReturn,
    CanManageEvaluation,
    CanManagePriceList,
)


class TenantQuerySetMixin:
    """فیلتر خودکار بر اساس tenant."""

    def get_queryset(self):
        qs = super().get_queryset()
        if hasattr(self.request, "tenant"):
            return qs.filter(tenant=self.request.tenant)
        return qs

    def perform_create(self, serializer):
        kwargs = {"id": uuid4()}
        if hasattr(self.request, "tenant"):
            kwargs["tenant"] = self.request.tenant
        serializer.save(**kwargs)


# ═══════════════════════════════════════════════════
# 1. Vendor Management
# ═══════════════════════════════════════════════════

class VendorCategoryViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت دسته‌بندی تأمین‌کنندگان.

    list: لیست دسته‌بندی‌ها
    create: ایجاد دسته‌بندی جدید
    retrieve: جزئیات دسته‌بندی
    update: بروزرسانی دسته‌بندی
    destroy: حذف دسته‌بندی
    """

    queryset = VendorCategoryModel.objects.all()
    permission_classes = [CanManageVendors]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["is_active", "level", "parent_category"]
    search_fields = ["category_code", "category_name"]
    ordering_fields = ["category_name", "category_code", "created_at"]
    ordering = ["category_name"]

    def get_serializer_class(self):
        if self.action == "list":
            return VendorCategoryListSerializer
        return VendorCategorySerializer


class VendorViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت تأمین‌کنندگان.

    list: لیست تأمین‌کنندگان
    create: ایجاد تأمین‌کننده جدید
    retrieve: جزئیات تأمین‌کننده
    update: بروزرسانی تأمین‌کننده
    block: مسدود کردن تأمین‌کننده
    activate: فعال‌سازی تأمین‌کننده
    contacts: لیست تماس‌های تأمین‌کننده
    bank_accounts: لیست حساب‌های بانکی
    addresses: لیست آدرس‌ها
    """

    queryset = VendorModel.objects.all()
    permission_classes = [CanManageVendors]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "vendor_type", "category", "is_active"]
    search_fields = [
        "vendor_code", "vendor_name", "vendor_name_en",
        "national_id", "email", "phone",
    ]
    ordering_fields = ["vendor_name", "vendor_code", "created_at"]
    ordering = ["vendor_name"]

    def get_serializer_class(self):
        if self.action == "list":
            return VendorListSerializer
        if self.action == "create":
            return VendorCreateSerializer
        if self.action == "block":
            return VendorBlockSerializer
        return VendorSerializer

    @action(detail=True, methods=["post"], url_path="block")
    def block(self, request, pk=None):
        """مسدود کردن تأمین‌کننده."""
        vendor = self.get_object()
        serializer = VendorBlockSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        vendor.status = "BLOCKED"
        vendor.is_active = False
        vendor.notes = serializer.validated_data.get("reason", vendor.notes)
        vendor.save()

        return Response(
            VendorSerializer(vendor).data,
            status=status.HTTP_200_OK,
        )

    @action(detail=True, methods=["post"], url_path="activate")
    def activate(self, request, pk=None):
        """فعال‌سازی تأمین‌کننده."""
        vendor = self.get_object()

        vendor.status = "ACTIVE"
        vendor.is_active = True
        vendor.save()

        return Response(
            VendorSerializer(vendor).data,
            status=status.HTTP_200_OK,
        )

    @action(detail=True, methods=["get"], url_path="contacts")
    def contacts(self, request, pk=None):
        """تماس‌های تأمین‌کننده."""
        contacts = VendorContactModel.objects.filter(vendor_id=pk)
        if hasattr(request, "tenant"):
            contacts = contacts.filter(tenant=request.tenant)
        serializer = VendorContactSerializer(contacts, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="bank-accounts")
    def bank_accounts(self, request, pk=None):
        """حساب‌های بانکی تأمین‌کننده."""
        accounts = VendorBankAccountModel.objects.filter(vendor_id=pk)
        if hasattr(request, "tenant"):
            accounts = accounts.filter(tenant=request.tenant)
        serializer = VendorBankAccountSerializer(accounts, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="addresses")
    def addresses(self, request, pk=None):
        """آدرس‌های تأمین‌کننده."""
        addresses = VendorAddressModel.objects.filter(vendor_id=pk)
        if hasattr(request, "tenant"):
            addresses = addresses.filter(tenant=request.tenant)
        serializer = VendorAddressSerializer(addresses, many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="evaluations")
    def evaluations(self, request, pk=None):
        """ارزیابی‌های تأمین‌کننده."""
        evals = VendorEvaluationModel.objects.filter(vendor_id=pk)
        if hasattr(request, "tenant"):
            evals = evals.filter(tenant=request.tenant)
        serializer = EvaluationListSerializer(evals.order_by("-evaluation_date"), many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="purchase-orders")
    def purchase_orders(self, request, pk=None):
        """سفارش‌های خرید تأمین‌کننده."""
        pos = PurchaseOrderModel.objects.filter(vendor_id=pk)
        if hasattr(request, "tenant"):
            pos = pos.filter(tenant=request.tenant)
        serializer = POListSerializer(pos.order_by("-created_at"), many=True)
        return Response(serializer.data)


class VendorContactViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت تماس‌های تأمین‌کننده."""

    queryset = VendorContactModel.objects.all()
    serializer_class = VendorContactSerializer
    permission_classes = [CanManageVendors]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["vendor", "is_primary", "is_active"]


class VendorBankAccountViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت حساب‌های بانکی تأمین‌کننده."""

    queryset = VendorBankAccountModel.objects.all()
    serializer_class = VendorBankAccountSerializer
    permission_classes = [CanManageVendors]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["vendor", "is_default", "is_active"]


class VendorAddressViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت آدرس‌های تأمین‌کننده."""

    queryset = VendorAddressModel.objects.all()
    serializer_class = VendorAddressSerializer
    permission_classes = [CanManageVendors]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["vendor", "address_type", "is_default"]


# ═══════════════════════════════════════════════════
# 2. Purchase Requisition
# ═══════════════════════════════════════════════════

class PurchaseRequisitionViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت درخواست‌های خرید.

    list: لیست درخواست‌ها
    create: ایجاد درخواست خرید جدید
    retrieve: جزئیات درخواست
    submit: ارسال برای تأیید
    approve: تأیید درخواست
    reject: رد درخواست
    cancel: لغو درخواست
    pending: درخواست‌های در انتظار تأیید
    """

    queryset = PurchaseRequisitionModel.objects.all()
    permission_classes = [CanManagePR]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "priority", "department", "requester_id"]
    search_fields = ["pr_number", "title", "requester_name"]
    ordering_fields = ["pr_number", "required_date", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return PRListSerializer
        if self.action == "create":
            return PRCreateSerializer
        if self.action == "reject":
            return PRRejectSerializer
        return PRSerializer

    @action(detail=True, methods=["post"], url_path="submit")
    def submit(self, request, pk=None):
        """ارسال درخواست خرید برای تأیید."""
        pr = self.get_object()
        if pr.status != "DRAFT":
            return Response(
                {"detail": "فقط درخواست‌های پیش‌نویس قابل ارسال هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        pr.status = "PENDING_APPROVAL"
        pr.request_date = timezone.now().date()
        pr.save(update_fields=["status", "request_date"])
        return Response(PRSerializer(pr).data)

    @action(detail=True, methods=["post"], url_path="approve")
    def approve(self, request, pk=None):
        """تأیید درخواست خرید."""
        pr = self.get_object()
        if pr.status != "PENDING_APPROVAL":
            return Response(
                {"detail": "فقط درخواست‌های در انتظار تأیید قابل تأیید هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        pr.status = "APPROVED"
        pr.approved_by_id = request.user.id
        pr.approved_at = timezone.now()
        pr.save(update_fields=["status", "approved_by_id", "approved_at"])
        return Response(PRSerializer(pr).data)

    @action(detail=True, methods=["post"], url_path="reject")
    def reject(self, request, pk=None):
        """رد درخواست خرید."""
        pr = self.get_object()
        if pr.status != "PENDING_APPROVAL":
            return Response(
                {"detail": "فقط درخواست‌های در انتظار تأیید قابل رد هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        serializer = PRRejectSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        pr.status = "REJECTED"
        pr.rejection_reason = serializer.validated_data.get("reason", "")
        pr.save(update_fields=["status", "rejection_reason"])
        return Response(PRSerializer(pr).data)

    @action(detail=True, methods=["post"], url_path="cancel")
    def cancel(self, request, pk=None):
        """لغو درخواست خرید."""
        pr = self.get_object()
        if pr.status in ("CONVERTED", "CANCELLED"):
            return Response(
                {"detail": "این درخواست قابل لغو نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        pr.status = "CANCELLED"
        pr.save(update_fields=["status"])
        return Response(PRSerializer(pr).data)

    @action(detail=False, methods=["get"], url_path="pending")
    def pending(self, request):
        """درخواست‌های در انتظار تأیید."""
        qs = self.get_queryset().filter(
            status="PENDING_APPROVAL"
        ).order_by("created_at")
        serializer = PRListSerializer(qs, many=True)
        return Response(serializer.data)


# ═══════════════════════════════════════════════════
# 3. RFQ
# ═══════════════════════════════════════════════════

class RFQViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت درخواست‌های استعلام قیمت.

    list: لیست استعلام‌ها
    create: ایجاد استعلام جدید
    retrieve: جزئیات استعلام
    send: ارسال استعلام به تأمین‌کنندگان
    close: بستن استعلام
    award: انتخاب برنده
    cancel: لغو استعلام
    """

    queryset = RFQModel.objects.all()
    permission_classes = [CanManageRFQ]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "buyer_id"]
    search_fields = ["rfq_number", "title", "buyer_name"]
    ordering_fields = ["rfq_number", "closing_date", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return RFQListSerializer
        if self.action == "award":
            return RFQAwardSerializer
        return RFQSerializer

    @action(detail=True, methods=["post"], url_path="send")
    def send(self, request, pk=None):
        """ارسال استعلام به تأمین‌کنندگان."""
        rfq = self.get_object()
        if rfq.status != "DRAFT":
            return Response(
                {"detail": "فقط استعلام‌های پیش‌نویس قابل ارسال هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        rfq.status = "SENT"
        rfq.issue_date = timezone.now().date()
        rfq.save(update_fields=["status", "issue_date"])
        return Response(RFQSerializer(rfq).data)

    @action(detail=True, methods=["post"], url_path="close")
    def close(self, request, pk=None):
        """بستن استعلام."""
        rfq = self.get_object()
        if rfq.status != "SENT":
            return Response(
                {"detail": "فقط استعلام‌های ارسال‌شده قابل بسته شدن هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        rfq.status = "CLOSED"
        rfq.save(update_fields=["status"])
        return Response(RFQSerializer(rfq).data)

    @action(detail=True, methods=["post"], url_path="award")
    def award(self, request, pk=None):
        """انتخاب برنده استعلام."""
        rfq = self.get_object()
        if rfq.status not in ("SENT", "CLOSED"):
            return Response(
                {"detail": "این استعلام در وضعیت مناسب برای انتخاب برنده نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        serializer = RFQAwardSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        vendor_id = serializer.validated_data["vendor_id"]
        # Mark awarded vendor response
        RFQVendorResponseModel.objects.filter(
            rfq=rfq, vendor_id=vendor_id
        ).update(status="AWARDED")
        # Mark others as rejected
        RFQVendorResponseModel.objects.filter(rfq=rfq).exclude(
            vendor_id=vendor_id
        ).update(status="REJECTED")

        rfq.status = "AWARDED"
        rfq.save(update_fields=["status"])
        return Response(RFQSerializer(rfq).data)

    @action(detail=True, methods=["post"], url_path="cancel")
    def cancel(self, request, pk=None):
        """لغو استعلام."""
        rfq = self.get_object()
        if rfq.status in ("AWARDED", "CANCELLED"):
            return Response(
                {"detail": "این استعلام قابل لغو نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        rfq.status = "CANCELLED"
        rfq.save(update_fields=["status"])
        return Response(RFQSerializer(rfq).data)


class RFQVendorResponseViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت پاسخ‌های تأمین‌کنندگان به استعلام."""

    queryset = RFQVendorResponseModel.objects.all()
    serializer_class = RFQVendorResponseSerializer
    permission_classes = [CanManageRFQ]
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ["rfq", "vendor_id", "status"]


# ═══════════════════════════════════════════════════
# 4. Purchase Order
# ═══════════════════════════════════════════════════

class PurchaseOrderViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت سفارش‌های خرید.

    list: لیست سفارش‌ها
    create: ایجاد سفارش جدید
    retrieve: جزئیات سفارش
    submit: ارسال برای تأیید
    approve: تأیید سفارش
    reject: رد سفارش
    send_to_vendor: ارسال به تأمین‌کننده
    cancel: لغو سفارش
    close: بستن سفارش
    goods_receipts: رسیدهای کالای مرتبط
    """

    queryset = PurchaseOrderModel.objects.all()
    permission_classes = [CanManagePO]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "priority", "vendor_id", "buyer_id"]
    search_fields = ["po_number", "title", "vendor__vendor_name", "vendor__vendor_code"]
    ordering_fields = ["po_number", "order_date", "total_amount", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return POListSerializer
        if self.action == "create":
            return POCreateSerializer
        if self.action == "reject":
            return PORejectSerializer
        return POSerializer

    @action(detail=True, methods=["post"], url_path="submit")
    def submit(self, request, pk=None):
        """ارسال سفارش خرید برای تأیید."""
        po = self.get_object()
        if po.status != "DRAFT":
            return Response(
                {"detail": "فقط سفارش‌های پیش‌نویس قابل ارسال هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        po.status = "PENDING_APPROVAL"
        po.save(update_fields=["status"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["post"], url_path="approve")
    def approve(self, request, pk=None):
        """تأیید سفارش خرید."""
        po = self.get_object()
        if po.status != "PENDING_APPROVAL":
            return Response(
                {"detail": "فقط سفارش‌های در انتظار تأیید قابل تأیید هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        po.status = "APPROVED"
        po.approved_by_id = request.user.id
        po.approved_at = timezone.now()
        po.save(update_fields=["status", "approved_by_id", "approved_at"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["post"], url_path="reject")
    def reject(self, request, pk=None):
        """رد سفارش خرید."""
        po = self.get_object()
        if po.status != "PENDING_APPROVAL":
            return Response(
                {"detail": "فقط سفارش‌های در انتظار تأیید قابل رد هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        serializer = PORejectSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        po.status = "REJECTED"
        po.rejection_reason = serializer.validated_data.get("reason", "")
        po.save(update_fields=["status", "rejection_reason"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["post"], url_path="send-to-vendor")
    def send_to_vendor(self, request, pk=None):
        """ارسال سفارش خرید به تأمین‌کننده."""
        po = self.get_object()
        if po.status != "APPROVED":
            return Response(
                {"detail": "فقط سفارش‌های تأییدشده قابل ارسال هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        po.status = "SENT"
        po.order_date = timezone.now().date()
        po.save(update_fields=["status", "order_date"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["post"], url_path="cancel")
    def cancel(self, request, pk=None):
        """لغو سفارش خرید."""
        po = self.get_object()
        if po.status in ("FULLY_RECEIVED", "CLOSED", "CANCELLED"):
            return Response(
                {"detail": "این سفارش قابل لغو نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        po.status = "CANCELLED"
        po.save(update_fields=["status"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["post"], url_path="close")
    def close(self, request, pk=None):
        """بستن سفارش خرید."""
        po = self.get_object()
        if po.status not in ("SENT", "PARTIALLY_RECEIVED", "FULLY_RECEIVED"):
            return Response(
                {"detail": "این سفارش در وضعیت مناسب برای بستن نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        po.status = "CLOSED"
        po.save(update_fields=["status"])
        return Response(POSerializer(po).data)

    @action(detail=True, methods=["get"], url_path="goods-receipts")
    def goods_receipts(self, request, pk=None):
        """رسیدهای کالای مرتبط با سفارش."""
        grs = GoodsReceiptModel.objects.filter(po_id=pk)
        if hasattr(request, "tenant"):
            grs = grs.filter(tenant=request.tenant)
        serializer = GRListSerializer(grs.order_by("-receipt_date"), many=True)
        return Response(serializer.data)

    @action(detail=True, methods=["get"], url_path="returns")
    def returns(self, request, pk=None):
        """مرجوعی‌های مرتبط با سفارش."""
        returns = PurchaseReturnModel.objects.filter(po_id=pk)
        if hasattr(request, "tenant"):
            returns = returns.filter(tenant=request.tenant)
        serializer = ReturnListSerializer(returns.order_by("-return_date"), many=True)
        return Response(serializer.data)


# ═══════════════════════════════════════════════════
# 5. Goods Receipt
# ═══════════════════════════════════════════════════

class GoodsReceiptViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت رسید کالا.

    list: لیست رسیدها
    create: ایجاد رسید جدید
    retrieve: جزئیات رسید
    confirm: تأیید رسید
    cancel: لغو رسید
    """

    queryset = GoodsReceiptModel.objects.all()
    permission_classes = [CanManageGR]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "po_id", "vendor_id"]
    search_fields = ["gr_number", "po__po_number", "vendor__vendor_name"]
    ordering_fields = ["gr_number", "receipt_date", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return GRListSerializer
        if self.action == "create":
            return GRCreateSerializer
        return GRSerializer

    @action(detail=True, methods=["post"], url_path="confirm")
    def confirm(self, request, pk=None):
        """تأیید رسید کالا."""
        gr = self.get_object()
        if gr.status != "DRAFT":
            return Response(
                {"detail": "فقط رسیدهای پیش‌نویس قابل تأیید هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        gr.status = "CONFIRMED"
        gr.posting_date = timezone.now().date()
        gr.save(update_fields=["status", "posting_date"])

        # Update PO receipt status
        if gr.po_id:
            self._update_po_receipt_status(gr.po_id)

        return Response(GRSerializer(gr).data)

    @action(detail=True, methods=["post"], url_path="cancel")
    def cancel(self, request, pk=None):
        """لغو رسید کالا."""
        gr = self.get_object()
        if gr.status == "CANCELLED":
            return Response(
                {"detail": "این رسید قبلاً لغو شده است."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        gr.status = "CANCELLED"
        gr.save(update_fields=["status"])

        # Reverse PO receipt status if needed
        if gr.po_id:
            self._update_po_receipt_status(gr.po_id)

        return Response(GRSerializer(gr).data)

    def _update_po_receipt_status(self, po_id):
        """بروزرسانی وضعیت دریافت سفارش خرید."""
        try:
            po = PurchaseOrderModel.objects.get(id=po_id)
        except PurchaseOrderModel.DoesNotExist:
            return

        # Check all PO lines to determine receipt status
        all_received = True
        any_received = False
        for line in po.lines.all():
            confirmed_grs = GoodsReceiptModel.objects.filter(
                po_id=po_id, status="CONFIRMED"
            )
            received_qty = sum(
                gl.accepted_quantity or 0
                for gr in confirmed_grs
                for gl in gr.lines.filter(po_line_id=line.id)
            )
            line.received_quantity = received_qty
            line.save(update_fields=["received_quantity"])

            if received_qty > 0:
                any_received = True
            if received_qty < line.quantity:
                all_received = False

        if all_received and any_received:
            po.status = "FULLY_RECEIVED"
        elif any_received:
            po.status = "PARTIALLY_RECEIVED"
        po.save(update_fields=["status"])


# ═══════════════════════════════════════════════════
# 6. Purchase Return
# ═══════════════════════════════════════════════════

class PurchaseReturnViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت مرجوعی خرید.

    list: لیست مرجوعی‌ها
    create: ایجاد مرجوعی جدید
    retrieve: جزئیات مرجوعی
    submit: ارسال برای تأیید
    approve: تأیید مرجوعی
    complete: تکمیل مرجوعی
    cancel: لغو مرجوعی
    """

    queryset = PurchaseReturnModel.objects.all()
    permission_classes = [CanManageReturn]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "po_id", "vendor_id"]
    search_fields = ["return_number", "vendor__vendor_name"]
    ordering_fields = ["return_number", "return_date", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return ReturnListSerializer
        return ReturnSerializer

    @action(detail=True, methods=["post"], url_path="submit")
    def submit(self, request, pk=None):
        """ارسال مرجوعی برای تأیید."""
        ret = self.get_object()
        if ret.status != "DRAFT":
            return Response(
                {"detail": "فقط مرجوعی‌های پیش‌نویس قابل ارسال هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        ret.status = "PENDING_APPROVAL"
        ret.save(update_fields=["status"])
        return Response(ReturnSerializer(ret).data)

    @action(detail=True, methods=["post"], url_path="approve")
    def approve(self, request, pk=None):
        """تأیید مرجوعی."""
        ret = self.get_object()
        if ret.status != "PENDING_APPROVAL":
            return Response(
                {"detail": "فقط مرجوعی‌های در انتظار تأیید قابل تأیید هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        ret.status = "APPROVED"
        ret.approved_by_id = request.user.id
        ret.approved_at = timezone.now()
        ret.save(update_fields=["status", "approved_by_id", "approved_at"])
        return Response(ReturnSerializer(ret).data)

    @action(detail=True, methods=["post"], url_path="complete")
    def complete(self, request, pk=None):
        """تکمیل مرجوعی (ارسال شده به تأمین‌کننده)."""
        ret = self.get_object()
        if ret.status != "APPROVED":
            return Response(
                {"detail": "فقط مرجوعی‌های تأییدشده قابل تکمیل هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        ret.status = "COMPLETED"
        ret.save(update_fields=["status"])
        return Response(ReturnSerializer(ret).data)

    @action(detail=True, methods=["post"], url_path="cancel")
    def cancel(self, request, pk=None):
        """لغو مرجوعی."""
        ret = self.get_object()
        if ret.status in ("COMPLETED", "CANCELLED"):
            return Response(
                {"detail": "این مرجوعی قابل لغو نیست."},
                status=status.HTTP_400_BAD_REQUEST,
            )
        ret.status = "CANCELLED"
        ret.save(update_fields=["status"])
        return Response(ReturnSerializer(ret).data)


# ═══════════════════════════════════════════════════
# 7. Vendor Evaluation
# ═══════════════════════════════════════════════════

class EvaluationCriteriaViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت معیارهای ارزیابی."""

    queryset = EvaluationCriteriaModel.objects.all()
    serializer_class = EvaluationCriteriaSerializer
    permission_classes = [CanManageEvaluation]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ["is_active"]
    search_fields = ["criteria_code", "criteria_name"]
    ordering = ["criteria_name"]


class EvaluationPeriodViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت دوره‌های ارزیابی."""

    queryset = EvaluationPeriodModel.objects.all()
    serializer_class = EvaluationPeriodSerializer
    permission_classes = [CanManageEvaluation]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    filterset_fields = ["is_active"]
    search_fields = ["period_name"]
    ordering = ["-start_date"]


class VendorEvaluationViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت ارزیابی تأمین‌کنندگان.

    list: لیست ارزیابی‌ها
    create: ایجاد ارزیابی جدید
    retrieve: جزئیات ارزیابی
    complete: تکمیل ارزیابی و محاسبه امتیاز
    """

    queryset = VendorEvaluationModel.objects.all()
    permission_classes = [CanManageEvaluation]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["status", "vendor_id", "period_id", "rating"]
    search_fields = ["vendor__vendor_name", "evaluator_name"]
    ordering_fields = ["evaluation_date", "total_score", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return EvaluationListSerializer
        return EvaluationSerializer

    @action(detail=True, methods=["post"], url_path="complete")
    def complete(self, request, pk=None):
        """تکمیل ارزیابی و محاسبه امتیاز نهایی."""
        evaluation = self.get_object()
        if evaluation.status != "DRAFT":
            return Response(
                {"detail": "فقط ارزیابی‌های پیش‌نویس قابل تکمیل هستند."},
                status=status.HTTP_400_BAD_REQUEST,
            )

        # Calculate total weighted score
        scores = VendorEvaluationScoreModel.objects.filter(evaluation=evaluation)
        if not scores.exists():
            return Response(
                {"detail": "حداقل یک امتیاز باید ثبت شود."},
                status=status.HTTP_400_BAD_REQUEST,
            )

        total_weight = sum(s.weight or 0 for s in scores)
        total_weighted = sum(
            ((s.score or 0) * (s.weight or 0)) for s in scores
        )
        total_score = total_weighted / total_weight if total_weight > 0 else 0

        # Update weighted scores
        for s in scores:
            s.weighted_score = (s.score or 0) * (s.weight or 0) / total_weight if total_weight > 0 else 0
            s.save(update_fields=["weighted_score"])

        # Determine rating
        if total_score >= 90:
            rating = "EXCELLENT"
        elif total_score >= 75:
            rating = "GOOD"
        elif total_score >= 60:
            rating = "AVERAGE"
        elif total_score >= 40:
            rating = "POOR"
        else:
            rating = "UNACCEPTABLE"

        evaluation.status = "COMPLETED"
        evaluation.total_score = round(total_score, 2)
        evaluation.rating = rating
        evaluation.save(update_fields=["status", "total_score", "rating"])

        return Response(EvaluationSerializer(evaluation).data)

    @action(detail=True, methods=["get", "post"], url_path="scores")
    def scores(self, request, pk=None):
        """مدیریت امتیازات ارزیابی."""
        evaluation = self.get_object()

        if request.method == "GET":
            scores = VendorEvaluationScoreModel.objects.filter(evaluation=evaluation)
            serializer = EvaluationScoreSerializer(scores, many=True)
            return Response(serializer.data)

        # POST: add scores
        serializer = EvaluationScoreSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        kwargs = {"id": uuid4(), "evaluation": evaluation}
        if hasattr(request, "tenant"):
            kwargs["tenant"] = request.tenant
        serializer.save(**kwargs)
        return Response(serializer.data, status=status.HTTP_201_CREATED)


# ═══════════════════════════════════════════════════
# 8. Price Management
# ═══════════════════════════════════════════════════

class VendorPriceListViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """
    API مدیریت لیست قیمت تأمین‌کنندگان.

    list: لیست قیمت‌ها
    create: ایجاد لیست قیمت جدید
    retrieve: جزئیات لیست قیمت
    items: آیتم‌های لیست قیمت
    """

    queryset = VendorPriceListModel.objects.all()
    permission_classes = [CanManagePriceList]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ["vendor_id", "is_active"]
    search_fields = ["price_list_name", "vendor__vendor_name"]
    ordering_fields = ["price_list_name", "valid_from", "created_at"]
    ordering = ["-created_at"]

    def get_serializer_class(self):
        if self.action == "list":
            return PriceListListSerializer
        return PriceListSerializer

    @action(detail=True, methods=["get", "post"], url_path="items")
    def items(self, request, pk=None):
        """مدیریت آیتم‌های لیست قیمت."""
        price_list = self.get_object()

        if request.method == "GET":
            items = VendorPriceListItemModel.objects.filter(price_list=price_list)
            serializer = PriceListItemSerializer(items, many=True)
            return Response(serializer.data)

        # POST: add item
        serializer = PriceListItemSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        kwargs = {"id": uuid4(), "price_list": price_list}
        if hasattr(request, "tenant"):
            kwargs["tenant"] = request.tenant
        serializer.save(**kwargs)
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class PurchaseDiscountViewSet(TenantQuerySetMixin, viewsets.ModelViewSet):
    """API مدیریت تخفیف‌های خرید."""

    queryset = PurchaseDiscountModel.objects.all()
    serializer_class = DiscountSerializer
    permission_classes = [CanManagePriceList]
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_fields = ["vendor_id", "discount_type", "is_active"]
    ordering_fields = ["valid_from", "created_at"]
    ordering = ["-created_at"]
