"""
SCM Use Cases — Purchase Return Operations.

عملیات مدیریت برگشت از خرید.
"""
from dataclasses import dataclass
from decimal import Decimal
from uuid import uuid4

from ..dtos.scm_dtos import CreateReturnDTO, ReturnResponseDTO
from ...domain.entities.purchase_return import (
    PurchaseReturn, PurchaseReturnLine, ReturnStatus, ReturnReason,
)
from ...domain.repositories.interfaces import IPurchaseReturnRepository
from ...domain.exceptions import ReturnNotFoundError


@dataclass
class CreateReturnUseCase:
    """Use Case — ایجاد برگشت از خرید."""
    return_repo: IPurchaseReturnRepository

    def execute(self, dto: CreateReturnDTO, tenant_id=None) -> ReturnResponseDTO:
        lines = []
        for idx, line_dto in enumerate(dto.lines, start=1):
            line = PurchaseReturnLine(
                id=uuid4(),
                tenant_id=tenant_id,
                line_number=idx,
                gr_line_id=line_dto.gr_line_id,
                po_line_id=line_dto.po_line_id,
                item_id=line_dto.item_id,
                item_code=line_dto.item_code,
                item_name=line_dto.item_name,
                return_quantity=Decimal(line_dto.return_quantity),
                uom_id=line_dto.uom_id,
                uom_code=line_dto.uom_code,
                unit_cost=Decimal(line_dto.unit_cost),
                reason=ReturnReason(line_dto.reason) if line_dto.reason else ReturnReason.OTHER,
                reason_detail=line_dto.reason_detail,
                warehouse_id=line_dto.warehouse_id,
                batch_number=line_dto.batch_number,
                notes=line_dto.notes,
            )
            lines.append(line)

        ret = PurchaseReturn(
            id=uuid4(),
            tenant_id=tenant_id,
            return_number=dto.return_number,
            status=ReturnStatus.DRAFT,
            po_id=dto.po_id,
            po_number=dto.po_number,
            gr_id=dto.gr_id,
            gr_number=dto.gr_number,
            vendor_id=dto.vendor_id,
            vendor_name=dto.vendor_name,
            requester_id=dto.requester_id,
            requester_name=dto.requester_name,
            return_date=dto.return_date,
            currency_code=dto.currency_code,
            notes=dto.notes,
            lines=lines,
        )
        ret.calculate_totals()

        saved = self.return_repo.save(ret)

        return ReturnResponseDTO(
            id=saved.id,
            return_number=saved.return_number,
            status=saved.status.value if saved.status else "",
            po_number=saved.po_number,
            vendor_name=saved.vendor_name,
            return_date=saved.return_date,
            total_amount=str(saved.total_amount),
            created_at=saved.created_at,
        )


@dataclass
class SubmitReturnUseCase:
    """Use Case — ارسال برگشت برای تأیید."""
    return_repo: IPurchaseReturnRepository

    def execute(self, return_id) -> ReturnResponseDTO:
        ret = self.return_repo.get_by_id(return_id)
        if not ret:
            raise ReturnNotFoundError(str(return_id))

        ret.submit()
        saved = self.return_repo.save(ret)

        return ReturnResponseDTO(
            id=saved.id,
            return_number=saved.return_number,
            status=saved.status.value if saved.status else "",
        )


@dataclass
class ApproveReturnUseCase:
    """Use Case — تأیید برگشت."""
    return_repo: IPurchaseReturnRepository

    def execute(self, return_id, approved_by) -> ReturnResponseDTO:
        ret = self.return_repo.get_by_id(return_id)
        if not ret:
            raise ReturnNotFoundError(str(return_id))

        ret.approve(approved_by)
        saved = self.return_repo.save(ret)

        return ReturnResponseDTO(
            id=saved.id,
            return_number=saved.return_number,
            status=saved.status.value if saved.status else "",
        )


@dataclass
class CompleteReturnUseCase:
    """Use Case — تکمیل برگشت."""
    return_repo: IPurchaseReturnRepository

    def execute(self, return_id) -> ReturnResponseDTO:
        ret = self.return_repo.get_by_id(return_id)
        if not ret:
            raise ReturnNotFoundError(str(return_id))

        ret.complete()
        saved = self.return_repo.save(ret)

        return ReturnResponseDTO(
            id=saved.id,
            return_number=saved.return_number,
            status=saved.status.value if saved.status else "",
        )


@dataclass
class CancelReturnUseCase:
    """Use Case — لغو برگشت."""
    return_repo: IPurchaseReturnRepository

    def execute(self, return_id) -> ReturnResponseDTO:
        ret = self.return_repo.get_by_id(return_id)
        if not ret:
            raise ReturnNotFoundError(str(return_id))

        ret.cancel()
        saved = self.return_repo.save(ret)

        return ReturnResponseDTO(
            id=saved.id,
            return_number=saved.return_number,
            status=saved.status.value if saved.status else "",
        )
