"""
SCM Use Cases — RFQ Operations.

عملیات مدیریت استعلام قیمت.
"""
from dataclasses import dataclass
from decimal import Decimal
from uuid import uuid4

from ..dtos.scm_dtos import CreateRFQDTO, RFQResponseDTO, SubmitVendorResponseDTO
from ...domain.entities.rfq import (
    RFQ, RFQLine, RFQVendorResponse, RFQVendorResponseLine,
    RFQStatus, RFQResponseStatus,
)
from ...domain.repositories.interfaces import IRFQRepository
from ...domain.exceptions import RFQNotFoundError


@dataclass
class CreateRFQUseCase:
    """Use Case — ایجاد استعلام."""
    rfq_repo: IRFQRepository

    def execute(self, dto: CreateRFQDTO, tenant_id=None) -> RFQResponseDTO:
        lines = []
        for idx, line_dto in enumerate(dto.lines, start=1):
            line = RFQLine(
                id=uuid4(),
                tenant_id=tenant_id,
                line_number=idx,
                item_id=line_dto.item_id,
                item_code=line_dto.item_code,
                item_name=line_dto.item_name,
                description=line_dto.description,
                quantity=Decimal(line_dto.quantity),
                uom_id=line_dto.uom_id,
                uom_code=line_dto.uom_code,
                required_date=line_dto.required_date,
                notes=line_dto.notes,
            )
            lines.append(line)

        rfq = RFQ(
            id=uuid4(),
            tenant_id=tenant_id,
            rfq_number=dto.rfq_number,
            title=dto.title,
            description=dto.description,
            status=RFQStatus.DRAFT,
            pr_id=dto.pr_id,
            closing_date=dto.closing_date,
            required_date=dto.required_date,
            buyer_id=dto.buyer_id,
            buyer_name=dto.buyer_name,
            currency_code=dto.currency_code,
            notes=dto.notes,
            lines=lines,
            invited_vendor_ids=dto.invited_vendor_ids,
        )
        rfq.validate()

        saved = self.rfq_repo.save(rfq)

        return RFQResponseDTO(
            id=saved.id,
            rfq_number=saved.rfq_number,
            title=saved.title,
            status=saved.status.value if saved.status else "",
            closing_date=saved.closing_date,
            buyer_name=saved.buyer_name,
            currency_code=saved.currency_code,
            created_at=saved.created_at,
        )


@dataclass
class SendRFQUseCase:
    """Use Case — ارسال استعلام به تأمین‌کنندگان."""
    rfq_repo: IRFQRepository

    def execute(self, rfq_id) -> RFQResponseDTO:
        rfq = self.rfq_repo.get_by_id(rfq_id)
        if not rfq:
            raise RFQNotFoundError(str(rfq_id))

        rfq.send()
        saved = self.rfq_repo.save(rfq)

        return RFQResponseDTO(
            id=saved.id,
            rfq_number=saved.rfq_number,
            title=saved.title,
            status=saved.status.value if saved.status else "",
            issue_date=saved.issue_date,
        )


@dataclass
class CloseRFQUseCase:
    """Use Case — بستن استعلام."""
    rfq_repo: IRFQRepository

    def execute(self, rfq_id) -> RFQResponseDTO:
        rfq = self.rfq_repo.get_by_id(rfq_id)
        if not rfq:
            raise RFQNotFoundError(str(rfq_id))

        rfq.close()
        saved = self.rfq_repo.save(rfq)

        return RFQResponseDTO(
            id=saved.id,
            rfq_number=saved.rfq_number,
            title=saved.title,
            status=saved.status.value if saved.status else "",
        )


@dataclass
class AwardRFQUseCase:
    """Use Case — واگذاری استعلام به تأمین‌کننده."""
    rfq_repo: IRFQRepository

    def execute(self, rfq_id, vendor_id) -> RFQResponseDTO:
        rfq = self.rfq_repo.get_by_id(rfq_id)
        if not rfq:
            raise RFQNotFoundError(str(rfq_id))

        rfq.award(vendor_id)
        saved = self.rfq_repo.save(rfq)

        return RFQResponseDTO(
            id=saved.id,
            rfq_number=saved.rfq_number,
            title=saved.title,
            status=saved.status.value if saved.status else "",
        )


@dataclass
class CancelRFQUseCase:
    """Use Case — لغو استعلام."""
    rfq_repo: IRFQRepository

    def execute(self, rfq_id) -> RFQResponseDTO:
        rfq = self.rfq_repo.get_by_id(rfq_id)
        if not rfq:
            raise RFQNotFoundError(str(rfq_id))

        rfq.cancel()
        saved = self.rfq_repo.save(rfq)

        return RFQResponseDTO(
            id=saved.id,
            rfq_number=saved.rfq_number,
            title=saved.title,
            status=saved.status.value if saved.status else "",
        )
