"""
Inventory Domain Events — رویدادهای دامنه انبار.

رویدادهای داخلی ماژول انبار. برای رویدادهای عمومی (cross-module)
از contracts/v1/events.py استفاده کنید.
"""
from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal
from typing import Optional
from uuid import UUID


# ═══════════════════════════════════════════════════
# Base
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class InventoryDomainEvent:
    """رویداد پایه دامنه انبار."""
    event_id: UUID
    tenant_id: UUID
    occurred_at: datetime
    version: int = 1


# ═══════════════════════════════════════════════════
# Master Data Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class ItemCreated(InventoryDomainEvent):
    """کالای جدید ایجاد شد."""
    event_type: str = "inventory.item.created"
    item_id: UUID = None
    item_code: str = ""
    item_name: str = ""
    item_type_id: Optional[UUID] = None


@dataclass(frozen=True)
class ItemUpdated(InventoryDomainEvent):
    """کالا بروزرسانی شد."""
    event_type: str = "inventory.item.updated"
    item_id: UUID = None
    item_code: str = ""
    changed_fields: list = field(default_factory=list)


@dataclass(frozen=True)
class ItemActivated(InventoryDomainEvent):
    """کالا فعال شد."""
    event_type: str = "inventory.item.activated"
    item_id: UUID = None
    item_code: str = ""


@dataclass(frozen=True)
class ItemDeactivated(InventoryDomainEvent):
    """کالا غیرفعال شد."""
    event_type: str = "inventory.item.deactivated"
    item_id: UUID = None
    item_code: str = ""


@dataclass(frozen=True)
class ItemObsoleted(InventoryDomainEvent):
    """کالا منسوخ شد."""
    event_type: str = "inventory.item.obsoleted"
    item_id: UUID = None
    item_code: str = ""


# ═══════════════════════════════════════════════════
# Warehouse Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class WarehouseCreated(InventoryDomainEvent):
    """انبار جدید ایجاد شد."""
    event_type: str = "inventory.warehouse.created"
    warehouse_id: UUID = None
    warehouse_code: str = ""
    warehouse_name: str = ""


@dataclass(frozen=True)
class WarehouseActivated(InventoryDomainEvent):
    """انبار فعال شد."""
    event_type: str = "inventory.warehouse.activated"
    warehouse_id: UUID = None


@dataclass(frozen=True)
class WarehouseDeactivated(InventoryDomainEvent):
    """انبار غیرفعال شد."""
    event_type: str = "inventory.warehouse.deactivated"
    warehouse_id: UUID = None


# ═══════════════════════════════════════════════════
# Stock Movement Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class GoodsReceived(InventoryDomainEvent):
    """رسید کالا ثبت شد."""
    event_type: str = "inventory.stock.goods_received"
    sle_id: UUID = None
    item_id: UUID = None
    warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")
    source_document_type: str = ""
    source_document_id: Optional[UUID] = None


@dataclass(frozen=True)
class GoodsIssued(InventoryDomainEvent):
    """حواله کالا ثبت شد."""
    event_type: str = "inventory.stock.goods_issued"
    sle_id: UUID = None
    item_id: UUID = None
    warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")
    source_document_type: str = ""
    source_document_id: Optional[UUID] = None


@dataclass(frozen=True)
class StockTransferred(InventoryDomainEvent):
    """انتقال موجودی."""
    event_type: str = "inventory.stock.transferred"
    sle_id: UUID = None
    item_id: UUID = None
    from_warehouse_id: UUID = None
    to_warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")


@dataclass(frozen=True)
class StockAdjusted(InventoryDomainEvent):
    """تعدیل موجودی."""
    event_type: str = "inventory.stock.adjusted"
    sle_id: UUID = None
    item_id: UUID = None
    warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")
    reason_code: str = ""


@dataclass(frozen=True)
class NegativeStockDetected(InventoryDomainEvent):
    """موجودی منفی شناسایی شد."""
    event_type: str = "inventory.stock.negative_detected"
    item_id: UUID = None
    warehouse_id: UUID = None
    current_balance: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Batch & Serial Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class BatchCreated(InventoryDomainEvent):
    """بچ جدید ایجاد شد."""
    event_type: str = "inventory.batch.created"
    batch_id: UUID = None
    batch_number: str = ""
    item_id: UUID = None


@dataclass(frozen=True)
class BatchExpired(InventoryDomainEvent):
    """بچ منقضی شد."""
    event_type: str = "inventory.batch.expired"
    batch_id: UUID = None
    batch_number: str = ""
    item_id: UUID = None


@dataclass(frozen=True)
class BatchBlocked(InventoryDomainEvent):
    """بچ مسدود شد."""
    event_type: str = "inventory.batch.blocked"
    batch_id: UUID = None
    reason: str = ""


@dataclass(frozen=True)
class SerialCreated(InventoryDomainEvent):
    """شماره سریال ایجاد شد."""
    event_type: str = "inventory.serial.created"
    serial_id: UUID = None
    serial_no: str = ""
    item_id: UUID = None


@dataclass(frozen=True)
class SerialStatusChanged(InventoryDomainEvent):
    """وضعیت سریال تغییر کرد."""
    event_type: str = "inventory.serial.status_changed"
    serial_id: UUID = None
    serial_no: str = ""
    old_status: str = ""
    new_status: str = ""


# ═══════════════════════════════════════════════════
# Reservation Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class StockReserved(InventoryDomainEvent):
    """موجودی رزرو شد."""
    event_type: str = "inventory.reservation.created"
    reservation_id: UUID = None
    item_id: UUID = None
    warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")
    source_document_type: str = ""
    source_document_id: Optional[UUID] = None


@dataclass(frozen=True)
class ReservationCancelled(InventoryDomainEvent):
    """رزرو لغو شد."""
    event_type: str = "inventory.reservation.cancelled"
    reservation_id: UUID = None
    item_id: UUID = None
    quantity: Decimal = Decimal("0")


@dataclass(frozen=True)
class ReservationExpired(InventoryDomainEvent):
    """رزرو منقضی شد."""
    event_type: str = "inventory.reservation.expired"
    reservation_id: UUID = None


@dataclass(frozen=True)
class StockAllocated(InventoryDomainEvent):
    """موجودی تخصیص یافت."""
    event_type: str = "inventory.allocation.created"
    allocation_id: UUID = None
    reservation_id: Optional[UUID] = None
    item_id: UUID = None
    warehouse_id: UUID = None
    quantity: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Costing Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class CostUpdated(InventoryDomainEvent):
    """بهای کالا بروزرسانی شد."""
    event_type: str = "inventory.costing.updated"
    item_id: UUID = None
    old_cost: Decimal = Decimal("0")
    new_cost: Decimal = Decimal("0")
    costing_method: str = ""


@dataclass(frozen=True)
class FinancialPostingCreated(InventoryDomainEvent):
    """ارسال مالی ایجاد شد."""
    event_type: str = "inventory.financial_posting.created"
    posting_id: UUID = None
    sle_id: UUID = None
    amount: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Physical Inventory Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class PhysicalInventoryStarted(InventoryDomainEvent):
    """شمارش فیزیکی شروع شد."""
    event_type: str = "inventory.physical_inventory.started"
    physical_inventory_id: UUID = None
    warehouse_id: Optional[UUID] = None


@dataclass(frozen=True)
class PhysicalInventoryCompleted(InventoryDomainEvent):
    """شمارش فیزیکی تکمیل شد."""
    event_type: str = "inventory.physical_inventory.completed"
    physical_inventory_id: UUID = None
    total_variance_value: Decimal = Decimal("0")


# ═══════════════════════════════════════════════════
# Quality Events
# ═══════════════════════════════════════════════════

@dataclass(frozen=True)
class InspectionLotCreated(InventoryDomainEvent):
    """لات بازرسی ایجاد شد."""
    event_type: str = "inventory.inspection.created"
    inspection_lot_id: UUID = None
    item_id: UUID = None
    inspection_type: str = ""


@dataclass(frozen=True)
class InspectionCompleted(InventoryDomainEvent):
    """بازرسی تکمیل شد."""
    event_type: str = "inventory.inspection.completed"
    inspection_lot_id: UUID = None
    quality_decision: str = ""


@dataclass(frozen=True)
class QualityActionTaken(InventoryDomainEvent):
    """اقدام کیفی انجام شد."""
    event_type: str = "inventory.quality_action.taken"
    action_id: UUID = None
    inspection_lot_id: UUID = None
    action_type: str = ""
    quantity: Decimal = Decimal("0")
