"""
Inventory ORM Models — Infrastructure Layer.

مدل‌های Django ORM ماژول انبار و موجودی.
تمام جداول با پیشوند inv_ هستند.
verbose_name‌ها به فارسی.

⚠️ مدل‌های مشترک از پلتفرم (Company, BusinessPartner, Currency) با FK ارجاع داده شده‌اند.
⚠️ مدل‌های ماژول‌های دیگر (User, Project, …) فقط با UUID رفرنس شده‌اند.
"""
import uuid

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from apps.core.tenant.models import TenantAwareModel


# ═══════════════════════════════════════════════════════════════════════════
# 1️⃣  MASTER DATA
# ═══════════════════════════════════════════════════════════════════════════


class ItemTypeModel(TenantAwareModel):
    """نوع کالا."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    type_code = models.CharField(_("کد"), max_length=50, db_index=True)
    type_name = models.CharField(_("نام"), max_length=100)
    description = models.TextField(_("توضیحات"), blank=True)
    is_active = models.BooleanField(_("فعال"), default=True, db_index=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)
    created_by = models.UUIDField(_("ایجاد توسط"), null=True, blank=True)
    updated_by = models.UUIDField(_("بروزرسانی توسط"), null=True, blank=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item_type"
        verbose_name = _("نوع کالا")
        verbose_name_plural = _("انواع کالا")
        unique_together = [["tenant", "type_code"]]
        indexes = [models.Index(fields=["tenant", "is_active"])]

    def __str__(self):
        return self.type_name


class ItemGroupModel(TenantAwareModel):
    """گروه / دسته‌بندی کالا — سلسله‌مراتبی."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    group_code = models.CharField(_("کد"), max_length=50, db_index=True)
    group_name = models.CharField(_("نام"), max_length=255)
    parent_group = models.ForeignKey(
        "self", on_delete=models.SET_NULL, null=True, blank=True,
        related_name="children", verbose_name=_("گروه مادر"),
    )
    level = models.PositiveIntegerField(_("سطح"), default=0)
    default_costing_method = models.ForeignKey(
        "CostingMethodModel", on_delete=models.SET_NULL, null=True, blank=True,
        related_name="+", verbose_name=_("روش قیمت‌گذاری پیش‌فرض"),
    )
    is_active = models.BooleanField(_("فعال"), default=True, db_index=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)
    created_by = models.UUIDField(_("ایجاد توسط"), null=True, blank=True)
    updated_by = models.UUIDField(_("بروزرسانی توسط"), null=True, blank=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item_group"
        verbose_name = _("گروه کالا")
        verbose_name_plural = _("گروه‌های کالا")
        unique_together = [["tenant", "group_code"]]
        indexes = [models.Index(fields=["tenant", "is_active"])]

    def __str__(self):
        return self.group_name


class UnitOfMeasureModel(TenantAwareModel):
    """واحد اندازه‌گیری."""

    class UOMType(models.TextChoices):
        QUANTITY = "QUANTITY", _("تعداد")
        WEIGHT = "WEIGHT", _("وزن")
        VOLUME = "VOLUME", _("حجم")
        LENGTH = "LENGTH", _("طول")
        AREA = "AREA", _("مساحت")
        TIME = "TIME", _("زمان")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    uom_code = models.CharField(_("کد"), max_length=20)
    uom_name = models.CharField(_("نام"), max_length=100)
    uom_name_local = models.CharField(_("نام فارسی"), max_length=100, blank=True)
    uom_type = models.CharField(
        _("نوع"), max_length=20,
        choices=UOMType.choices, default=UOMType.QUANTITY,
    )
    decimal_places = models.PositiveSmallIntegerField(_("اعشار"), default=0)
    is_active = models.BooleanField(_("فعال"), default=True, db_index=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_unit_of_measure"
        verbose_name = _("واحد اندازه‌گیری")
        verbose_name_plural = _("واحدهای اندازه‌گیری")
        unique_together = [["tenant", "uom_code"]]

    def __str__(self):
        return f"{self.uom_code} — {self.uom_name}"


class ItemModel(TenantAwareModel):
    """کالا — جدول اصلی."""

    class ItemStatus(models.TextChoices):
        ACTIVE = "ACTIVE", _("فعال")
        INACTIVE = "INACTIVE", _("غیرفعال")
        OBSOLETE = "OBSOLETE", _("منسوخ")

    class ABCClassification(models.TextChoices):
        A = "A", "A"
        B = "B", "B"
        C = "C", "C"

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    item_code = models.CharField(_("کد کالا"), max_length=50, db_index=True)
    item_name = models.CharField(_("نام کالا"), max_length=255)
    item_name_local = models.CharField(_("نام فارسی"), max_length=255, blank=True)
    item_description = models.TextField(_("توضیحات"), blank=True)

    item_type = models.ForeignKey(
        ItemTypeModel, on_delete=models.PROTECT, null=True, blank=True,
        related_name="items", verbose_name=_("نوع کالا"),
    )
    item_group = models.ForeignKey(
        ItemGroupModel, on_delete=models.SET_NULL, null=True, blank=True,
        related_name="items", verbose_name=_("گروه کالا"),
    )
    base_uom = models.ForeignKey(
        UnitOfMeasureModel, on_delete=models.PROTECT, null=True, blank=True,
        related_name="+", verbose_name=_("واحد اندازه‌گیری پایه"),
    )

    # Tracking
    is_batch_managed = models.BooleanField(_("مدیریت بچ"), default=False)
    is_serial_managed = models.BooleanField(_("مدیریت سریال"), default=False)
    is_expiry_managed = models.BooleanField(_("مدیریت انقضا"), default=False)
    abc_classification = models.CharField(
        _("طبقه‌بندی ABC"), max_length=1,
        choices=ABCClassification.choices, blank=True,
    )
    item_status = models.CharField(
        _("وضعیت"), max_length=20,
        choices=ItemStatus.choices, default=ItemStatus.ACTIVE, db_index=True,
    )

    # Flags
    is_purchasable = models.BooleanField(_("قابل خرید"), default=True)
    is_saleable = models.BooleanField(_("قابل فروش"), default=True)
    is_stockable = models.BooleanField(_("قابل انبارش"), default=True)
    is_producible = models.BooleanField(_("قابل تولید"), default=False)

    # Planning
    lead_time_days = models.PositiveIntegerField(_("زمان تأمین (روز)"), default=0)
    shelf_life_days = models.PositiveIntegerField(
        _("عمر مفید (روز)"), null=True, blank=True
    )
    default_warehouse = models.ForeignKey(
        "WarehouseModel", on_delete=models.SET_NULL, null=True, blank=True,
        related_name="+", verbose_name=_("انبار پیش‌فرض"),
    )

    # Owner
    company = models.ForeignKey(
        "core_organization.Company", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="+",
        verbose_name=_("شرکت مالک"),
    )

    # Audit
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)
    created_by = models.UUIDField(_("ایجاد توسط"), null=True, blank=True)
    updated_by = models.UUIDField(_("بروزرسانی توسط"), null=True, blank=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item"
        verbose_name = _("کالا")
        verbose_name_plural = _("کالاها")
        unique_together = [["tenant", "item_code"]]
        indexes = [
            models.Index(fields=["tenant", "item_status"]),
            models.Index(fields=["tenant", "item_type"]),
            models.Index(fields=["tenant", "item_group"]),
        ]

    def __str__(self):
        return f"{self.item_code} — {self.item_name}"


class ItemAttributeModel(TenantAwareModel):
    """ویژگی کالا."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    item = models.ForeignKey(
        ItemModel, on_delete=models.CASCADE,
        related_name="attributes", verbose_name=_("کالا"),
    )
    attribute_name = models.CharField(_("نام ویژگی"), max_length=255)
    attribute_value = models.TextField(_("مقدار"))
    attribute_data_type = models.CharField(
        _("نوع داده"), max_length=20, default="Text",
    )
    display_order = models.PositiveIntegerField(_("ترتیب نمایش"), default=0)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item_attribute"
        verbose_name = _("ویژگی کالا")
        verbose_name_plural = _("ویژگی‌های کالا")
        ordering = ["display_order"]

    def __str__(self):
        return f"{self.attribute_name}: {self.attribute_value}"


class ItemUOMModel(TenantAwareModel):
    """واحد اندازه‌گیری کالا — تبدیل‌ها."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    item = models.ForeignKey(
        ItemModel, on_delete=models.CASCADE,
        related_name="uoms", verbose_name=_("کالا"),
    )
    uom = models.ForeignKey(
        UnitOfMeasureModel, on_delete=models.PROTECT,
        related_name="+", verbose_name=_("واحد"),
    )
    conversion_factor = models.DecimalField(
        _("ضریب تبدیل"), max_digits=18, decimal_places=6, default=1,
    )
    is_base_uom = models.BooleanField(_("واحد پایه"), default=False)
    is_purchase_uom = models.BooleanField(_("واحد خرید"), default=False)
    is_sales_uom = models.BooleanField(_("واحد فروش"), default=False)
    is_stock_uom = models.BooleanField(_("واحد انبار"), default=False)
    barcode = models.CharField(_("بارکد"), max_length=100, blank=True)
    is_active = models.BooleanField(_("فعال"), default=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item_uom"
        verbose_name = _("واحد کالا")
        verbose_name_plural = _("واحدهای کالا")
        unique_together = [["item", "uom"]]

    def __str__(self):
        return f"{self.item.item_code} — {self.uom.uom_code} (×{self.conversion_factor})"


# ═══════════════════════════════════════════════════════════════════════════
# 2️⃣  WAREHOUSE & LOCATION
# ═══════════════════════════════════════════════════════════════════════════


class WarehouseModel(TenantAwareModel):
    """انبار."""

    class WarehouseType(models.TextChoices):
        PHYSICAL = "PHYSICAL", _("فیزیکی")
        VIRTUAL = "VIRTUAL", _("مجازی")
        TRANSIT = "TRANSIT", _("ترانزیت")
        QUARANTINE = "QUARANTINE", _("قرنطینه")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    warehouse_code = models.CharField(_("کد انبار"), max_length=50, db_index=True)
    warehouse_name = models.CharField(_("نام انبار"), max_length=255)
    company = models.ForeignKey(
        "core_organization.Company", on_delete=models.SET_NULL,
        null=True, blank=True, related_name="+",
        verbose_name=_("شرکت"),
    )
    warehouse_type = models.CharField(
        _("نوع"), max_length=20,
        choices=WarehouseType.choices, default=WarehouseType.PHYSICAL,
    )

    # Address
    address = models.TextField(_("آدرس"), blank=True)
    city = models.CharField(_("شهر"), max_length=100, blank=True)
    province = models.CharField(_("استان"), max_length=100, blank=True)
    country = models.CharField(_("کشور"), max_length=5, default="IR")
    postal_code = models.CharField(_("کد پستی"), max_length=20, blank=True)
    phone = models.CharField(_("تلفن"), max_length=50, blank=True)
    email = models.EmailField(_("ایمیل"), blank=True)

    # Manager
    manager_user_id = models.UUIDField(
        _("مدیر انبار"), null=True, blank=True
    )

    # Settings
    is_negative_stock_allowed = models.BooleanField(
        _("اجازه موجودی منفی"), default=False
    )
    is_active = models.BooleanField(_("فعال"), default=True, db_index=True)

    # HRM Location reference
    hrm_location_id = models.UUIDField(
        _("مکان HRM"), null=True, blank=True,
        help_text=_("ارجاع به Location ماژول HRM"),
    )

    # Audit
    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)
    created_by = models.UUIDField(_("ایجاد توسط"), null=True, blank=True)
    updated_by = models.UUIDField(_("بروزرسانی توسط"), null=True, blank=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_warehouse"
        verbose_name = _("انبار")
        verbose_name_plural = _("انبارها")
        unique_together = [["tenant", "warehouse_code"]]
        indexes = [
            models.Index(fields=["tenant", "is_active"]),
            models.Index(fields=["tenant", "warehouse_type"]),
        ]

    def __str__(self):
        return f"{self.warehouse_code} — {self.warehouse_name}"


class StorageLocationModel(TenantAwareModel):
    """مکان ذخیره‌سازی — سلسله‌مراتبی."""

    class LocationType(models.TextChoices):
        ZONE = "ZONE", _("ناحیه")
        AISLE = "AISLE", _("راهرو")
        RACK = "RACK", _("قفسه")
        SHELF = "SHELF", _("طبقه")
        BIN = "BIN", _("سلول")

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    location_code = models.CharField(_("کد مکان"), max_length=50)
    location_name = models.CharField(_("نام مکان"), max_length=255)
    warehouse = models.ForeignKey(
        WarehouseModel, on_delete=models.CASCADE,
        related_name="locations", verbose_name=_("انبار"),
    )
    parent_location = models.ForeignKey(
        "self", on_delete=models.CASCADE, null=True, blank=True,
        related_name="children", verbose_name=_("مکان مادر"),
    )
    location_type = models.CharField(
        _("نوع"), max_length=20,
        choices=LocationType.choices, default=LocationType.ZONE,
    )
    level = models.PositiveIntegerField(_("سطح"), default=0)

    is_picking_location = models.BooleanField(_("مکان برداشت"), default=False)
    is_putaway_location = models.BooleanField(_("مکان چینش"), default=False)

    max_weight_kg = models.DecimalField(
        _("حداکثر وزن (kg)"), max_digits=12, decimal_places=2,
        null=True, blank=True,
    )
    max_volume_cbm = models.DecimalField(
        _("حداکثر حجم (m³)"), max_digits=12, decimal_places=4,
        null=True, blank=True,
    )
    temperature = models.DecimalField(
        _("دما (°C)"), max_digits=6, decimal_places=2,
        null=True, blank=True,
    )
    is_hazardous_zone = models.BooleanField(_("ناحیه خطرناک"), default=False)
    is_active = models.BooleanField(_("فعال"), default=True, db_index=True)

    created_at = models.DateTimeField(_("تاریخ ایجاد"), auto_now_add=True)
    updated_at = models.DateTimeField(_("تاریخ بروزرسانی"), auto_now=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_storage_location"
        verbose_name = _("مکان ذخیره‌سازی")
        verbose_name_plural = _("مکان‌های ذخیره‌سازی")
        unique_together = [["warehouse", "location_code"]]
        indexes = [
            models.Index(fields=["tenant", "warehouse", "is_active"]),
        ]

    def __str__(self):
        return f"{self.warehouse.warehouse_code}/{self.location_code}"


class ItemWarehouseModel(TenantAwareModel):
    """تنظیمات کالا در انبار."""

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    item = models.ForeignKey(
        ItemModel, on_delete=models.CASCADE,
        related_name="warehouse_settings", verbose_name=_("کالا"),
    )
    warehouse = models.ForeignKey(
        WarehouseModel, on_delete=models.CASCADE,
        related_name="item_settings", verbose_name=_("انبار"),
    )

    min_stock_level = models.DecimalField(
        _("حداقل موجودی"), max_digits=18, decimal_places=4, default=0
    )
    max_stock_level = models.DecimalField(
        _("حداکثر موجودی"), max_digits=18, decimal_places=4, default=0
    )
    reorder_point = models.DecimalField(
        _("نقطه سفارش"), max_digits=18, decimal_places=4, default=0
    )
    safety_stock = models.DecimalField(
        _("موجودی ایمنی"), max_digits=18, decimal_places=4, default=0
    )
    reorder_quantity = models.DecimalField(
        _("مقدار سفارش"), max_digits=18, decimal_places=4, default=0
    )
    default_storage_location = models.ForeignKey(
        StorageLocationModel, on_delete=models.SET_NULL, null=True, blank=True,
        related_name="+", verbose_name=_("مکان پیش‌فرض"),
    )
    is_active = models.BooleanField(_("فعال"), default=True)

    class Meta:
        app_label = "inventory"
        db_table = "inv_item_warehouse"
        verbose_name = _("تنظیمات کالا-انبار")
        verbose_name_plural = _("تنظیمات کالا-انبار")
        unique_together = [["item", "warehouse"]]

    def __str__(self):
        return f"{self.item.item_code} @ {self.warehouse.warehouse_code}"
