"""
Inventory API Serializers — v1.

سریالایزرهای REST API ماژول انبار.
"""
from rest_framework import serializers

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 ItemTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ItemTypeModel
        fields = [
            "id", "type_code", "type_name", "description",
            "is_active",
        ]
        read_only_fields = ["id"]


class ItemGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = ItemGroupModel
        fields = [
            "id", "group_code", "group_name",
            "parent_group", "level", "default_costing_method",
            "is_active",
        ]
        read_only_fields = ["id", "level"]


class UnitOfMeasureSerializer(serializers.ModelSerializer):
    class Meta:
        model = UnitOfMeasureModel
        fields = [
            "id", "uom_code", "uom_name", "uom_name_local",
            "uom_type", "decimal_places", "is_active",
        ]
        read_only_fields = ["id"]


class ItemAttributeSerializer(serializers.ModelSerializer):
    class Meta:
        model = ItemAttributeModel
        fields = [
            "id", "item", "attribute_name", "attribute_value",
            "attribute_data_type", "display_order",
        ]
        read_only_fields = ["id"]


class ItemUOMSerializer(serializers.ModelSerializer):
    uom_name = serializers.CharField(source="uom.uom_name", read_only=True)

    class Meta:
        model = ItemUOMModel
        fields = [
            "id", "item", "uom", "uom_name",
            "conversion_factor", "is_base_uom",
            "is_purchase_uom", "is_sales_uom", "is_stock_uom",
            "barcode", "is_active",
        ]
        read_only_fields = ["id"]


class ItemListSerializer(serializers.ModelSerializer):
    """سریالایزر لیست — خلاصه."""
    item_type_name = serializers.CharField(
        source="item_type.type_name", read_only=True, default=""
    )
    item_group_name = serializers.CharField(
        source="item_group.group_name", read_only=True, default=""
    )
    base_uom_name = serializers.CharField(
        source="base_uom.uom_name", read_only=True, default=""
    )

    class Meta:
        model = ItemModel
        fields = [
            "id", "item_code", "item_name", "item_name_local",
            "item_type", "item_type_name",
            "item_group", "item_group_name",
            "base_uom", "base_uom_name",
            "item_status", "is_batch_managed",
            "is_serial_managed", "abc_classification",
        ]


class ItemDetailSerializer(serializers.ModelSerializer):
    """سریالایزر جزئیات کالا."""
    item_type_name = serializers.CharField(
        source="item_type.type_name", read_only=True, default=""
    )
    item_group_name = serializers.CharField(
        source="item_group.group_name", read_only=True, default=""
    )
    base_uom_name = serializers.CharField(
        source="base_uom.uom_name", read_only=True, default=""
    )
    attributes = ItemAttributeSerializer(many=True, read_only=True)
    uom_conversions = ItemUOMSerializer(many=True, read_only=True, source="uoms")

    class Meta:
        model = ItemModel
        fields = [
            "id", "item_code", "item_name", "item_name_local",
            "item_type", "item_type_name",
            "item_group", "item_group_name",
            "base_uom", "base_uom_name",
            "item_description",
            "item_status", "is_batch_managed", "is_serial_managed",
            "is_expiry_managed", "shelf_life_days",
            "is_purchasable", "is_saleable", "is_stockable", "is_producible",
            "lead_time_days", "default_warehouse",
            "abc_classification", "company",
            "attributes", "uom_conversions",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class ItemCreateSerializer(serializers.ModelSerializer):
    """سریالایزر ایجاد کالا."""
    class Meta:
        model = ItemModel
        fields = [
            "item_code", "item_name", "item_name_local",
            "item_type", "item_group", "base_uom",
            "item_description",
            "is_batch_managed", "is_serial_managed",
            "is_expiry_managed", "shelf_life_days",
            "is_purchasable", "is_saleable", "is_stockable", "is_producible",
            "lead_time_days", "default_warehouse",
            "abc_classification", "company",
        ]


# ═══════════════════════════════════════════════════
# 2️⃣  Warehouse & Location
# ═══════════════════════════════════════════════════

class StorageLocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = StorageLocationModel
        fields = [
            "id", "location_code", "location_name", "location_type",
            "warehouse", "parent_location", "is_active",
        ]
        read_only_fields = ["id"]


class WarehouseListSerializer(serializers.ModelSerializer):
    class Meta:
        model = WarehouseModel
        fields = [
            "id", "warehouse_code", "warehouse_name",
            "warehouse_type", "company", "is_active",
        ]


class WarehouseDetailSerializer(serializers.ModelSerializer):
    locations = StorageLocationSerializer(many=True, read_only=True)

    class Meta:
        model = WarehouseModel
        fields = [
            "id", "warehouse_code", "warehouse_name", "warehouse_type",
            "company", "manager_user_id",
            "address", "city", "province", "country",
            "postal_code", "phone", "email",
            "is_negative_stock_allowed", "is_active",
            "hrm_location_id",
            "locations", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class WarehouseCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = WarehouseModel
        fields = [
            "warehouse_code", "warehouse_name", "warehouse_type",
            "company", "manager_user_id",
            "address", "city", "province", "country",
            "postal_code", "phone", "email",
            "is_negative_stock_allowed",
        ]


class ItemWarehouseSerializer(serializers.ModelSerializer):
    class Meta:
        model = ItemWarehouseModel
        fields = [
            "id", "item", "warehouse", "default_storage_location",
            "reorder_point", "safety_stock",
            "is_active",
        ]
        read_only_fields = ["id"]


# ═══════════════════════════════════════════════════
# 3️⃣  Stock Status & Ledger
# ═══════════════════════════════════════════════════

class StockStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = StockStatusModel
        fields = [
            "id", "status_code", "status_name", "status_type",
            "is_available_for_sales", "is_available_for_production",
            "is_blocked_for_movement", "sort_order", "is_active",
        ]
        read_only_fields = ["id"]


class StockLedgerEntrySerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)
    item_name = serializers.CharField(source="item.item_name", read_only=True)
    warehouse_code = serializers.CharField(source="warehouse.warehouse_code", read_only=True)
    uom_name = serializers.CharField(source="uom.uom_name", read_only=True)

    class Meta:
        model = StockLedgerEntryModel
        fields = [
            "id", "entry_number", "posting_date",
            "item", "item_code", "item_name",
            "warehouse", "warehouse_code",
            "location", "batch", "serial_number",
            "stock_status", "transaction_type", "transaction_sub_type",
            "quantity", "uom", "uom_name", "quantity_in_base_uom",
            "unit_cost", "total_cost",
            "source_document_type", "source_document_id",
            "reason_code", "remarks", "is_reversed",
            "created_at",
        ]
        read_only_fields = ["id", "entry_number", "created_at"]


class StockBalanceSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)
    item_name = serializers.CharField(source="item.item_name", read_only=True)
    warehouse_code = serializers.CharField(source="warehouse.warehouse_code", read_only=True)
    warehouse_name = serializers.CharField(source="warehouse.warehouse_name", read_only=True)
    uom_name = serializers.CharField(source="uom.uom_name", read_only=True)

    class Meta:
        model = StockBalanceModel
        fields = [
            "id", "item", "item_code", "item_name",
            "warehouse", "warehouse_code", "warehouse_name",
            "location", "batch", "serial_number", "stock_status",
            "quantity_on_hand", "quantity_reserved",
            "quantity_allocated", "quantity_available",
            "quantity_in_transit", "uom", "uom_name",
            "average_unit_cost", "total_value",
            "last_movement_date", "last_updated",
        ]


# ═══════════════════════════════════════════════════
# 4️⃣  Batch & Serial
# ═══════════════════════════════════════════════════

class BatchSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)

    class Meta:
        model = BatchModel
        fields = [
            "id", "batch_number", "item", "item_code",
            "manufacturing_date", "expiry_date",
            "vendor_batch_number", "vendor",
            "batch_status", "quality_status",
            "batch_attributes", "is_active",
            "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


class SerialNumberSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)

    class Meta:
        model = SerialNumberModel
        fields = [
            "id", "serial_no", "item", "item_code", "batch",
            "manufacturing_date", "warranty_start_date",
            "warranty_end_date", "warranty_months",
            "current_warehouse", "current_location",
            "current_stock_status",
            "serial_status", "quality_status",
            "supplier_serial_number",
            "is_active", "created_at", "updated_at",
        ]
        read_only_fields = ["id", "created_at", "updated_at"]


# ═══════════════════════════════════════════════════
# 5️⃣  Costing
# ═══════════════════════════════════════════════════

class CostingMethodSerializer(serializers.ModelSerializer):
    class Meta:
        model = CostingMethodModel
        fields = ["id", "method_code", "method_name", "description", "is_active"]
        read_only_fields = ["id"]


class ItemCostingSerializer(serializers.ModelSerializer):
    class Meta:
        model = ItemCostingModel
        fields = [
            "id", "item", "company", "costing_method",
            "standard_cost", "moving_average_cost",
            "last_purchase_cost", "currency_code",
            "last_cost_update_date", "is_active",
        ]
        read_only_fields = ["id"]


# ═══════════════════════════════════════════════════
# 6️⃣  Reservation
# ═══════════════════════════════════════════════════

class StockReservationSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)
    warehouse_code = serializers.CharField(source="warehouse.warehouse_code", read_only=True)

    class Meta:
        model = StockReservationModel
        fields = [
            "id", "reservation_number", "reservation_date",
            "item", "item_code", "warehouse", "warehouse_code",
            "location", "batch", "serial_number",
            "reserved_quantity", "allocated_quantity",
            "uom", "source_document_type", "source_document_id",
            "priority_level", "expiry_date",
            "reservation_status", "required_by_date",
            "remarks", "created_at",
        ]
        read_only_fields = ["id", "reservation_number", "created_at"]


class StockAllocationSerializer(serializers.ModelSerializer):
    class Meta:
        model = StockAllocationModel
        fields = [
            "id", "allocation_number", "allocation_date",
            "reservation", "item", "warehouse", "location",
            "batch", "serial_number",
            "allocated_quantity", "picked_quantity", "uom",
            "allocation_status", "created_at",
        ]
        read_only_fields = ["id", "allocation_number", "created_at"]


# ═══════════════════════════════════════════════════
# 7️⃣  Physical Inventory
# ═══════════════════════════════════════════════════

class PhysicalInventoryLineSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)

    class Meta:
        model = PhysicalInventoryLineModel
        fields = [
            "id", "physical_inventory", "line_number",
            "item", "item_code", "warehouse", "location",
            "batch", "serial_number",
            "book_quantity", "uom",
            "first_count_quantity", "first_count_by", "first_count_date",
            "second_count_quantity", "third_count_quantity",
            "final_count_quantity",
            "variance_quantity", "variance_percent", "variance_value",
            "line_status", "variance_reason_code", "variance_remarks",
        ]
        read_only_fields = ["id"]


class PhysicalInventorySerializer(serializers.ModelSerializer):
    lines = PhysicalInventoryLineSerializer(many=True, read_only=True)

    class Meta:
        model = PhysicalInventoryModel
        fields = [
            "id", "inventory_number", "inventory_date",
            "inventory_type", "warehouse", "location",
            "inventory_status", "is_blind_count", "is_stock_frozen",
            "variance_threshold_percent",
            "scheduled_start_date", "actual_start_date", "completed_date",
            "responsible_user_id", "remarks",
            "lines", "created_at",
        ]
        read_only_fields = ["id", "inventory_number", "created_at"]


class CycleCountScheduleSerializer(serializers.ModelSerializer):
    class Meta:
        model = CycleCountScheduleModel
        fields = [
            "id", "schedule_name", "warehouse",
            "count_frequency_days", "item_group", "abc_class",
            "high_value_items_only",
            "next_count_date", "last_count_date", "is_active",
        ]
        read_only_fields = ["id"]


# ═══════════════════════════════════════════════════
# 8️⃣  Quality
# ═══════════════════════════════════════════════════

class InspectionResultSerializer(serializers.ModelSerializer):
    class Meta:
        model = InspectionResultModel
        fields = [
            "id", "inspection_lot", "inspection_characteristic",
            "target_value", "actual_value",
            "tolerance_lower", "tolerance_upper",
            "result_status", "tested_by", "tested_date", "remarks",
        ]
        read_only_fields = ["id"]


class InspectionLotSerializer(serializers.ModelSerializer):
    item_code = serializers.CharField(source="item.item_code", read_only=True)
    results = InspectionResultSerializer(many=True, read_only=True)

    class Meta:
        model = InspectionLotModel
        fields = [
            "id", "inspection_lot_number", "inspection_type",
            "inspection_date", "item", "item_code",
            "batch", "warehouse",
            "inspection_quantity", "sample_size", "uom",
            "inspection_status", "quality_decision",
            "inspection_start_date", "inspection_complete_date",
            "inspector_id", "remarks",
            "results", "created_at",
        ]
        read_only_fields = ["id", "inspection_lot_number", "created_at"]


class QualityActionSerializer(serializers.ModelSerializer):
    class Meta:
        model = QualityActionModel
        fields = [
            "id", "inspection_lot", "action_type", "action_date",
            "action_quantity", "target_stock_status",
            "action_by", "remarks", "completed_date",
        ]
        read_only_fields = ["id"]


# ═══════════════════════════════════════════════════
# 9️⃣  Stock Movement Input Serializers
# ═══════════════════════════════════════════════════

class GoodsReceiptInputSerializer(serializers.Serializer):
    """سریالایزر ورودی رسید کالا."""
    item_id = serializers.UUIDField()
    warehouse_id = serializers.UUIDField()
    location_id = serializers.UUIDField(required=False, allow_null=True)
    quantity = serializers.DecimalField(max_digits=18, decimal_places=4)
    uom_id = serializers.UUIDField()
    posting_date = serializers.DateField()
    unit_cost = serializers.DecimalField(max_digits=18, decimal_places=4, default=0)
    batch_id = serializers.UUIDField(required=False, allow_null=True)
    serial_numbers = serializers.ListField(
        child=serializers.CharField(), required=False, default=list
    )
    stock_status_id = serializers.UUIDField(required=False, allow_null=True)
    source_document_type = serializers.CharField(required=False, default="")
    source_document_id = serializers.UUIDField(required=False, allow_null=True)
    remarks = serializers.CharField(required=False, default="")


class GoodsIssueInputSerializer(serializers.Serializer):
    """سریالایزر ورودی حواله کالا."""
    item_id = serializers.UUIDField()
    warehouse_id = serializers.UUIDField()
    location_id = serializers.UUIDField(required=False, allow_null=True)
    quantity = serializers.DecimalField(max_digits=18, decimal_places=4)
    uom_id = serializers.UUIDField()
    posting_date = serializers.DateField()
    batch_id = serializers.UUIDField(required=False, allow_null=True)
    serial_numbers = serializers.ListField(
        child=serializers.CharField(), required=False, default=list
    )
    stock_status_id = serializers.UUIDField(required=False, allow_null=True)
    source_document_type = serializers.CharField(required=False, default="")
    source_document_id = serializers.UUIDField(required=False, allow_null=True)
    reason_code = serializers.CharField(required=False, default="")
    remarks = serializers.CharField(required=False, default="")


class StockTransferInputSerializer(serializers.Serializer):
    """سریالایزر ورودی انتقال."""
    item_id = serializers.UUIDField()
    from_warehouse_id = serializers.UUIDField()
    to_warehouse_id = serializers.UUIDField()
    quantity = serializers.DecimalField(max_digits=18, decimal_places=4)
    uom_id = serializers.UUIDField()
    posting_date = serializers.DateField()
    batch_id = serializers.UUIDField(required=False, allow_null=True)
    serial_numbers = serializers.ListField(
        child=serializers.CharField(), required=False, default=list
    )
    remarks = serializers.CharField(required=False, default="")


class StockAdjustmentInputSerializer(serializers.Serializer):
    """سریالایزر ورودی تعدیل."""
    item_id = serializers.UUIDField()
    warehouse_id = serializers.UUIDField()
    location_id = serializers.UUIDField(required=False, allow_null=True)
    adjustment_quantity = serializers.DecimalField(max_digits=18, decimal_places=4)
    uom_id = serializers.UUIDField()
    posting_date = serializers.DateField()
    reason_code = serializers.CharField(required=False, default="")
    batch_id = serializers.UUIDField(required=False, allow_null=True)
    remarks = serializers.CharField(required=False, default="")
