"""
Inventory API Views — v1.

ویوست‌های REST API ماژول انبار.
"""
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 .serializers import (
    # Master Data
    ItemTypeSerializer, ItemGroupSerializer,
    UnitOfMeasureSerializer,
    ItemListSerializer, ItemDetailSerializer, ItemCreateSerializer,
    ItemAttributeSerializer, ItemUOMSerializer,
    # Warehouse
    WarehouseListSerializer, WarehouseDetailSerializer,
    WarehouseCreateSerializer,
    StorageLocationSerializer, ItemWarehouseSerializer,
    # Stock
    StockStatusSerializer,
    StockLedgerEntrySerializer, StockBalanceSerializer,
    # Batch/Serial
    BatchSerializer, SerialNumberSerializer,
    # Costing
    CostingMethodSerializer, ItemCostingSerializer,
    # Reservation
    StockReservationSerializer, StockAllocationSerializer,
    # Physical Inventory
    PhysicalInventorySerializer, PhysicalInventoryLineSerializer,
    CycleCountScheduleSerializer,
    # Quality
    InspectionLotSerializer, InspectionResultSerializer,
    QualityActionSerializer,
    # Input
    GoodsReceiptInputSerializer, GoodsIssueInputSerializer,
    StockTransferInputSerializer, StockAdjustmentInputSerializer,
)
from .permissions import (
    CanManageMasterData, CanManageWarehouse, CanManageStock,
    CanManageBatchSerial, CanManageReservation,
    CanManagePhysicalInventory, CanManageQuality, CanManageCosting,
)
from ...infrastructure.persistence.models import (
    ItemTypeModel, ItemGroupModel, UnitOfMeasureModel,
    ItemModel, ItemAttributeModel, ItemUOMModel,
    WarehouseModel, StorageLocationModel, ItemWarehouseModel,
)
from ...infrastructure.persistence.models_extended import (
    StockStatusModel, BatchModel, SerialNumberModel,
    StockLedgerEntryModel, StockBalanceModel,
    CostingMethodModel, ItemCostingModel,
    StockReservationModel, StockAllocationModel,
    PhysicalInventoryModel, PhysicalInventoryLineModel,
    CycleCountScheduleModel,
    InspectionLotModel, InspectionResultModel, QualityActionModel,
)


# ═══════════════════════════════════════════════════
# 1️⃣  Master Data
# ═══════════════════════════════════════════════════

class ItemTypeViewSet(viewsets.ModelViewSet):
    """مدیریت نوع کالا."""
    serializer_class = ItemTypeSerializer
    permission_classes = [CanManageMasterData]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["type_code", "type_name"]
    filterset_fields = ["is_active"]

    def get_queryset(self):
        return ItemTypeModel.objects.filter(tenant=self.request.tenant)


class ItemGroupViewSet(viewsets.ModelViewSet):
    """مدیریت گروه کالا."""
    serializer_class = ItemGroupSerializer
    permission_classes = [CanManageMasterData]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["group_code", "group_name"]
    filterset_fields = ["is_active", "parent_group"]

    def get_queryset(self):
        return ItemGroupModel.objects.filter(tenant=self.request.tenant)

    @action(detail=False, methods=["get"])
    def tree(self, request):
        """ساختار درختی گروه‌ها."""
        roots = self.get_queryset().filter(parent_group__isnull=True)
        serializer = self.get_serializer(roots, many=True)
        return Response({"data": serializer.data})


class UnitOfMeasureViewSet(viewsets.ModelViewSet):
    """مدیریت واحد اندازه‌گیری."""
    serializer_class = UnitOfMeasureSerializer
    permission_classes = [CanManageMasterData]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["uom_code", "uom_name"]
    filterset_fields = ["uom_type", "is_active"]

    def get_queryset(self):
        return UnitOfMeasureModel.objects.filter(tenant=self.request.tenant)


class ItemViewSet(viewsets.ModelViewSet):
    """مدیریت کالا — CRUD + فعال/غیرفعال."""
    permission_classes = [CanManageMasterData]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["item_code", "item_name", "item_name_en", "barcode"]
    filterset_fields = ["item_type", "item_group", "item_status", "abc_classification"]
    ordering_fields = ["item_code", "item_name", "created_at"]
    ordering = ["-created_at"]

    def get_queryset(self):
        return ItemModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item_type", "item_group", "base_uom")

    def get_serializer_class(self):
        if self.action == "list":
            return ItemListSerializer
        if self.action in ("create",):
            return ItemCreateSerializer
        return ItemDetailSerializer

    @action(detail=True, methods=["post"])
    def activate(self, request, pk=None):
        """فعال کردن کالا."""
        item = self.get_object()
        item.item_status = "ACTIVE"
        item.save(update_fields=["item_status", "updated_at"])
        return Response({"data": {"status": "activated"}})

    @action(detail=True, methods=["post"])
    def deactivate(self, request, pk=None):
        """غیرفعال کردن کالا."""
        item = self.get_object()
        item.item_status = "INACTIVE"
        item.save(update_fields=["item_status", "updated_at"])
        return Response({"data": {"status": "deactivated"}})

    @action(detail=True, methods=["get"])
    def stock(self, request, pk=None):
        """موجودی کالا در همه انبارها."""
        balances = StockBalanceModel.objects.filter(
            tenant=request.tenant, item_id=pk
        ).select_related("warehouse", "uom")
        serializer = StockBalanceSerializer(balances, many=True)
        return Response({"data": serializer.data})


class ItemAttributeViewSet(viewsets.ModelViewSet):
    """مدیریت ویژگی‌های کالا."""
    serializer_class = ItemAttributeSerializer
    permission_classes = [CanManageMasterData]
    filterset_fields = ["item"]

    def get_queryset(self):
        return ItemAttributeModel.objects.filter(tenant=self.request.tenant)


class ItemUOMViewSet(viewsets.ModelViewSet):
    """مدیریت تبدیل واحدهای کالا."""
    serializer_class = ItemUOMSerializer
    permission_classes = [CanManageMasterData]
    filterset_fields = ["item"]

    def get_queryset(self):
        return ItemUOMModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("uom")


# ═══════════════════════════════════════════════════
# 2️⃣  Warehouse & Location
# ═══════════════════════════════════════════════════

class WarehouseViewSet(viewsets.ModelViewSet):
    """مدیریت انبار."""
    permission_classes = [CanManageWarehouse]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["warehouse_code", "warehouse_name"]
    filterset_fields = ["warehouse_type", "is_active", "company"]

    def get_queryset(self):
        return WarehouseModel.objects.filter(tenant=self.request.tenant)

    def get_serializer_class(self):
        if self.action == "list":
            return WarehouseListSerializer
        if self.action == "create":
            return WarehouseCreateSerializer
        return WarehouseDetailSerializer

    @action(detail=True, methods=["get"])
    def stock(self, request, pk=None):
        """موجودی انبار."""
        balances = StockBalanceModel.objects.filter(
            tenant=request.tenant, warehouse_id=pk
        ).select_related("item", "uom")
        serializer = StockBalanceSerializer(balances, many=True)
        return Response({"data": serializer.data})


class StorageLocationViewSet(viewsets.ModelViewSet):
    """مدیریت مکان‌های انبار."""
    serializer_class = StorageLocationSerializer
    permission_classes = [CanManageWarehouse]
    filterset_fields = ["warehouse", "location_type", "is_active"]

    def get_queryset(self):
        return StorageLocationModel.objects.filter(tenant=self.request.tenant)


class ItemWarehouseViewSet(viewsets.ModelViewSet):
    """تنظیمات کالا-انبار."""
    serializer_class = ItemWarehouseSerializer
    permission_classes = [CanManageWarehouse]
    filterset_fields = ["item", "warehouse", "is_active"]

    def get_queryset(self):
        return ItemWarehouseModel.objects.filter(tenant=self.request.tenant)


# ═══════════════════════════════════════════════════
# 3️⃣  Stock Status & Ledger
# ═══════════════════════════════════════════════════

class StockStatusViewSet(viewsets.ModelViewSet):
    """مدیریت وضعیت موجودی."""
    serializer_class = StockStatusSerializer
    permission_classes = [CanManageStock]
    filterset_fields = ["status_type", "is_active"]

    def get_queryset(self):
        return StockStatusModel.objects.filter(tenant=self.request.tenant)


class StockLedgerViewSet(viewsets.ReadOnlyModelViewSet):
    """مشاهده دفتر کل موجودی (فقط‌خواندنی)."""
    serializer_class = StockLedgerEntrySerializer
    permission_classes = [CanManageStock]
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_fields = ["item", "warehouse", "transaction_type", "batch", "serial_number"]
    ordering_fields = ["posting_date", "created_at"]
    ordering = ["-posting_date", "-created_at"]

    def get_queryset(self):
        return StockLedgerEntryModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item", "warehouse", "uom")


class StockBalanceViewSet(viewsets.ReadOnlyModelViewSet):
    """مشاهده موجودی فعلی (فقط‌خواندنی)."""
    serializer_class = StockBalanceSerializer
    permission_classes = [CanManageStock]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields = ["item__item_code", "item__item_name"]
    filterset_fields = ["item", "warehouse", "stock_status"]
    ordering_fields = ["item__item_code", "quantity_on_hand"]

    def get_queryset(self):
        return StockBalanceModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item", "warehouse", "uom")


class StockMovementViewSet(viewsets.ViewSet):
    """ثبت حرکات موجودی — رسید، حواله، انتقال، تعدیل."""
    permission_classes = [CanManageStock]

    @action(detail=False, methods=["post"], url_path="goods-receipt")
    def goods_receipt(self, request):
        """ثبت رسید کالا."""
        serializer = GoodsReceiptInputSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # TODO: wire to PostGoodsReceiptUseCase
        return Response(
            {"data": serializer.validated_data, "message": "رسید ثبت شد"},
            status=status.HTTP_201_CREATED,
        )

    @action(detail=False, methods=["post"], url_path="goods-issue")
    def goods_issue(self, request):
        """ثبت حواله کالا."""
        serializer = GoodsIssueInputSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(
            {"data": serializer.validated_data, "message": "حواله ثبت شد"},
            status=status.HTTP_201_CREATED,
        )

    @action(detail=False, methods=["post"], url_path="transfer")
    def transfer(self, request):
        """ثبت انتقال بین انبارها."""
        serializer = StockTransferInputSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(
            {"data": serializer.validated_data, "message": "انتقال ثبت شد"},
            status=status.HTTP_201_CREATED,
        )

    @action(detail=False, methods=["post"], url_path="adjustment")
    def adjustment(self, request):
        """ثبت تعدیل موجودی."""
        serializer = StockAdjustmentInputSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(
            {"data": serializer.validated_data, "message": "تعدیل ثبت شد"},
            status=status.HTTP_201_CREATED,
        )


# ═══════════════════════════════════════════════════
# 4️⃣  Batch & Serial
# ═══════════════════════════════════════════════════

class BatchViewSet(viewsets.ModelViewSet):
    """مدیریت بچ / لات."""
    serializer_class = BatchSerializer
    permission_classes = [CanManageBatchSerial]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["batch_number"]
    filterset_fields = ["item", "batch_status", "quality_status", "is_active"]

    def get_queryset(self):
        return BatchModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item")

    @action(detail=True, methods=["post"])
    def block(self, request, pk=None):
        """مسدود کردن بچ."""
        batch = self.get_object()
        batch.batch_status = "BLOCKED"
        batch.save(update_fields=["batch_status", "updated_at"])
        return Response({"data": {"status": "blocked"}})

    @action(detail=True, methods=["post"])
    def release(self, request, pk=None):
        """آزادسازی بچ."""
        batch = self.get_object()
        batch.batch_status = "ACTIVE"
        batch.save(update_fields=["batch_status", "updated_at"])
        return Response({"data": {"status": "released"}})


class SerialNumberViewSet(viewsets.ModelViewSet):
    """مدیریت شماره سریال."""
    serializer_class = SerialNumberSerializer
    permission_classes = [CanManageBatchSerial]
    filter_backends = [DjangoFilterBackend, filters.SearchFilter]
    search_fields = ["serial_no", "supplier_serial_number"]
    filterset_fields = ["item", "serial_status", "quality_status", "current_warehouse"]

    def get_queryset(self):
        return SerialNumberModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item")

    @action(detail=True, methods=["get"])
    def history(self, request, pk=None):
        """تاریخچه سریال."""
        from ...infrastructure.persistence.models_extended import SerialNumberHistoryModel
        histories = SerialNumberHistoryModel.objects.filter(
            tenant=request.tenant, serial_number_id=pk
        ).order_by("-transaction_date")
        # Basic response — could have its own serializer
        data = list(histories.values(
            "id", "transaction_date", "transaction_type",
            "from_warehouse_id", "to_warehouse_id", "remarks",
        ))
        return Response({"data": data})


# ═══════════════════════════════════════════════════
# 5️⃣  Costing
# ═══════════════════════════════════════════════════

class CostingMethodViewSet(viewsets.ModelViewSet):
    """مدیریت روش‌های قیمت‌گذاری."""
    serializer_class = CostingMethodSerializer
    permission_classes = [CanManageCosting]

    def get_queryset(self):
        return CostingMethodModel.objects.filter(tenant=self.request.tenant)


class ItemCostingViewSet(viewsets.ModelViewSet):
    """مدیریت قیمت‌گذاری کالا."""
    serializer_class = ItemCostingSerializer
    permission_classes = [CanManageCosting]
    filterset_fields = ["item", "costing_method"]

    def get_queryset(self):
        return ItemCostingModel.objects.filter(tenant=self.request.tenant)


# ═══════════════════════════════════════════════════
# 6️⃣  Reservation
# ═══════════════════════════════════════════════════

class StockReservationViewSet(viewsets.ModelViewSet):
    """مدیریت رزرو موجودی."""
    serializer_class = StockReservationSerializer
    permission_classes = [CanManageReservation]
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_fields = ["item", "warehouse", "reservation_status"]
    ordering_fields = ["reservation_date", "priority_level"]
    ordering = ["-reservation_date"]

    def get_queryset(self):
        return StockReservationModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item", "warehouse")

    @action(detail=True, methods=["post"])
    def cancel(self, request, pk=None):
        """لغو رزرو."""
        reservation = self.get_object()
        reservation.reservation_status = "CANCELLED"
        reservation.save(update_fields=["reservation_status", "updated_at"])
        return Response({"data": {"status": "cancelled"}})


class StockAllocationViewSet(viewsets.ModelViewSet):
    """مدیریت تخصیص."""
    serializer_class = StockAllocationSerializer
    permission_classes = [CanManageReservation]
    filterset_fields = ["item", "warehouse", "allocation_status", "reservation"]

    def get_queryset(self):
        return StockAllocationModel.objects.filter(tenant=self.request.tenant)


# ═══════════════════════════════════════════════════
# 7️⃣  Physical Inventory
# ═══════════════════════════════════════════════════

class PhysicalInventoryViewSet(viewsets.ModelViewSet):
    """مدیریت شمارش فیزیکی."""
    serializer_class = PhysicalInventorySerializer
    permission_classes = [CanManagePhysicalInventory]
    filterset_fields = ["inventory_type", "inventory_status", "warehouse"]

    def get_queryset(self):
        return PhysicalInventoryModel.objects.filter(tenant=self.request.tenant)

    @action(detail=True, methods=["post"])
    def start(self, request, pk=None):
        """شروع شمارش."""
        pi = self.get_object()
        pi.inventory_status = "IN_PROGRESS"
        pi.is_stock_frozen = True
        pi.save(update_fields=["inventory_status", "is_stock_frozen", "updated_at"])
        return Response({"data": {"status": "started"}})

    @action(detail=True, methods=["post"])
    def complete(self, request, pk=None):
        """تکمیل شمارش."""
        pi = self.get_object()
        pi.inventory_status = "COMPLETED"
        pi.is_stock_frozen = False
        pi.save(update_fields=["inventory_status", "is_stock_frozen", "updated_at"])
        return Response({"data": {"status": "completed"}})


class PhysicalInventoryLineViewSet(viewsets.ModelViewSet):
    """مدیریت اقلام شمارش."""
    serializer_class = PhysicalInventoryLineSerializer
    permission_classes = [CanManagePhysicalInventory]
    filterset_fields = ["physical_inventory", "line_status", "item"]

    def get_queryset(self):
        return PhysicalInventoryLineModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item")


class CycleCountScheduleViewSet(viewsets.ModelViewSet):
    """مدیریت برنامه شمارش چرخشی."""
    serializer_class = CycleCountScheduleSerializer
    permission_classes = [CanManagePhysicalInventory]
    filterset_fields = ["warehouse", "is_active"]

    def get_queryset(self):
        return CycleCountScheduleModel.objects.filter(tenant=self.request.tenant)


# ═══════════════════════════════════════════════════
# 8️⃣  Quality
# ═══════════════════════════════════════════════════

class InspectionLotViewSet(viewsets.ModelViewSet):
    """مدیریت لات بازرسی."""
    serializer_class = InspectionLotSerializer
    permission_classes = [CanManageQuality]
    filterset_fields = ["item", "inspection_type", "inspection_status", "quality_decision"]

    def get_queryset(self):
        return InspectionLotModel.objects.filter(
            tenant=self.request.tenant
        ).select_related("item")

    @action(detail=True, methods=["post"], url_path="start-inspection")
    def start_inspection(self, request, pk=None):
        """شروع بازرسی."""
        lot = self.get_object()
        lot.inspection_status = "IN_PROGRESS"
        lot.save(update_fields=["inspection_status", "updated_at"])
        return Response({"data": {"status": "in_progress"}})

    @action(detail=True, methods=["post"])
    def decide(self, request, pk=None):
        """ثبت تصمیم کیفی."""
        lot = self.get_object()
        decision = request.data.get("quality_decision")
        if decision not in ("ACCEPTED", "REJECTED", "CONDITIONAL", "REWORK"):
            return Response(
                {"error": {"message": "تصمیم نامعتبر"}},
                status=status.HTTP_400_BAD_REQUEST,
            )
        lot.quality_decision = decision
        lot.inspection_status = "COMPLETED"
        lot.save(update_fields=["quality_decision", "inspection_status", "updated_at"])
        return Response({"data": {"quality_decision": decision}})


class InspectionResultViewSet(viewsets.ModelViewSet):
    """مدیریت نتایج بازرسی."""
    serializer_class = InspectionResultSerializer
    permission_classes = [CanManageQuality]
    filterset_fields = ["inspection_lot", "result_status"]

    def get_queryset(self):
        return InspectionResultModel.objects.filter(tenant=self.request.tenant)


class QualityActionViewSet(viewsets.ModelViewSet):
    """مدیریت اقدامات کیفی."""
    serializer_class = QualityActionSerializer
    permission_classes = [CanManageQuality]
    filterset_fields = ["inspection_lot", "action_type"]

    def get_queryset(self):
        return QualityActionModel.objects.filter(tenant=self.request.tenant)
