"""
Inventory Use Cases — Master Data Operations.

Single-purpose handlers for item, warehouse, UOM management.
"""
from dataclasses import dataclass
from uuid import uuid4

from ..dtos.inventory_dtos import (
    CreateItemDTO, UpdateItemDTO, ItemResponseDTO,
    CreateItemTypeDTO, ItemTypeResponseDTO,
    CreateItemGroupDTO, ItemGroupResponseDTO,
    CreateUOMDTO, UOMResponseDTO,
    CreateWarehouseDTO, WarehouseResponseDTO,
)
from ...domain.entities.master_data import (
    Item, ItemType, ItemGroup, UnitOfMeasure, ItemStatus,
)
from ...domain.entities.warehouse import Warehouse
from ...domain.repositories.interfaces import IItemRepository, IWarehouseRepository
from ...domain.exceptions import DuplicateItemCodeError


@dataclass
class CreateItemUseCase:
    """
    Use Case — ایجاد کالای جدید.

    Flow:
    1. بررسی یکتایی کد کالا
    2. ایجاد entity
    3. اعتبارسنجی
    4. ذخیره
    5. بازگشت DTO
    """

    item_repo: IItemRepository

    def execute(self, dto: CreateItemDTO, tenant_id=None) -> ItemResponseDTO:
        # 1. Check uniqueness
        existing = self.item_repo.find_by_code(dto.item_code)
        if existing:
            raise DuplicateItemCodeError(dto.item_code)

        # 2. Create domain entity
        item = Item(
            id=uuid4(),
            tenant_id=tenant_id,
            item_code=dto.item_code,
            item_name=dto.item_name,
            item_name_en=dto.item_name_en,
            item_type_id=dto.item_type_id,
            item_group_id=dto.item_group_id,
            base_uom_id=dto.base_uom_id,
            barcode=dto.barcode,
            description=dto.description,
            brand=dto.brand,
            model=dto.model,
            manufacturer=dto.manufacturer,
            is_batch_tracked=dto.is_batch_tracked,
            is_serial_tracked=dto.is_serial_tracked,
            shelf_life_days=dto.shelf_life_days,
            default_warehouse_id=dto.default_warehouse_id,
            abc_classification=dto.abc_classification,
        )

        # 3. Validate
        item.validate()

        # 4. Persist
        saved = self.item_repo.save(item)

        # 5. Return response
        return ItemResponseDTO(
            id=saved.id,
            item_code=saved.item_code,
            item_name=saved.item_name,
            item_name_en=saved.item_name_en,
            item_type_id=saved.item_type_id,
            item_group_id=saved.item_group_id,
            base_uom_id=saved.base_uom_id,
            barcode=saved.barcode,
            status=saved.status,
            is_batch_tracked=saved.is_batch_tracked,
            is_serial_tracked=saved.is_serial_tracked,
            abc_classification=saved.abc_classification,
            is_active=saved.is_active,
            created_at=saved.created_at,
        )


@dataclass
class UpdateItemUseCase:
    """Use Case — بروزرسانی کالا."""

    item_repo: IItemRepository

    def execute(self, item_id, dto: UpdateItemDTO) -> ItemResponseDTO:
        item = self.item_repo.get_by_id(item_id)
        if not item:
            raise ValueError(f"کالا یافت نشد: {item_id}")

        if dto.item_name is not None:
            item.item_name = dto.item_name
        if dto.item_name_en is not None:
            item.item_name_en = dto.item_name_en
        if dto.description is not None:
            item.description = dto.description
        if dto.brand is not None:
            item.brand = dto.brand
        if dto.model is not None:
            item.model = dto.model
        if dto.barcode is not None:
            item.barcode = dto.barcode
        if dto.abc_classification is not None:
            item.abc_classification = dto.abc_classification
        if dto.is_active is not None:
            if dto.is_active:
                item.activate()
            else:
                item.deactivate()

        item.validate()
        saved = self.item_repo.save(item)

        return ItemResponseDTO(
            id=saved.id,
            item_code=saved.item_code,
            item_name=saved.item_name,
            status=saved.status,
            is_active=saved.is_active,
        )


@dataclass
class DeactivateItemUseCase:
    """Use Case — غیرفعال کردن کالا."""

    item_repo: IItemRepository

    def execute(self, item_id) -> ItemResponseDTO:
        item = self.item_repo.get_by_id(item_id)
        if not item:
            raise ValueError(f"کالا یافت نشد: {item_id}")

        item.deactivate()
        saved = self.item_repo.save(item)

        return ItemResponseDTO(
            id=saved.id,
            item_code=saved.item_code,
            item_name=saved.item_name,
            status=saved.status,
            is_active=saved.is_active,
        )
