"""
SCM Use Cases — Vendor Evaluation Operations.

عملیات مدیریت ارزیابی تأمین‌کنندگان.
"""
from dataclasses import dataclass
from decimal import Decimal
from uuid import uuid4

from ..dtos.scm_dtos import (
    CreateEvaluationDTO,
    EvaluationResponseDTO,
    CreateEvaluationCriteriaDTO,
    EvaluationCriteriaResponseDTO,
    CreateEvaluationPeriodDTO,
    EvaluationPeriodResponseDTO,
)
from ...domain.entities.vendor_evaluation import (
    VendorEvaluation,
    VendorEvaluationScore,
    EvaluationCriteria,
    EvaluationPeriod,
    EvaluationStatus,
)
from ...domain.repositories.interfaces import (
    IVendorEvaluationRepository,
    IEvaluationCriteriaRepository,
    IEvaluationPeriodRepository,
)
from ...domain.exceptions import EvaluationNotFoundError


@dataclass
class CreateEvaluationUseCase:
    """Use Case — ایجاد ارزیابی تأمین‌کننده."""
    eval_repo: IVendorEvaluationRepository
    criteria_repo: IEvaluationCriteriaRepository

    def execute(self, dto: CreateEvaluationDTO, tenant_id=None) -> EvaluationResponseDTO:
        scores = []
        for score_dto in dto.scores:
            criteria = self.criteria_repo.get_by_id(score_dto.criteria_id)
            score = VendorEvaluationScore(
                id=uuid4(),
                tenant_id=tenant_id,
                criteria_id=score_dto.criteria_id,
                criteria_name=criteria.criteria_name if criteria else "",
                weight=criteria.weight if criteria else Decimal("0"),
                score=Decimal(score_dto.score),
                comments=score_dto.comments,
            )
            scores.append(score)

        evaluation = VendorEvaluation(
            id=uuid4(),
            tenant_id=tenant_id,
            vendor_id=dto.vendor_id,
            vendor_name=dto.vendor_name,
            period_id=dto.period_id,
            evaluator_id=dto.evaluator_id,
            evaluator_name=dto.evaluator_name,
            status=EvaluationStatus.DRAFT,
            evaluation_date=dto.evaluation_date,
            comments=dto.comments,
            scores=scores,
        )
        evaluation.validate()

        saved = self.eval_repo.save(evaluation)

        return EvaluationResponseDTO(
            id=saved.id,
            vendor_name=saved.vendor_name,
            evaluator_name=saved.evaluator_name,
            status=saved.status.value if saved.status else "",
            evaluation_date=saved.evaluation_date,
            total_score=str(saved.total_score),
            rating=saved.rating.value if saved.rating else "",
            created_at=saved.created_at,
        )


@dataclass
class CompleteEvaluationUseCase:
    """Use Case — تکمیل ارزیابی."""
    eval_repo: IVendorEvaluationRepository

    def execute(self, evaluation_id) -> EvaluationResponseDTO:
        evaluation = self.eval_repo.get_by_id(evaluation_id)
        if not evaluation:
            raise EvaluationNotFoundError(str(evaluation_id))

        evaluation.complete()
        saved = self.eval_repo.save(evaluation)

        return EvaluationResponseDTO(
            id=saved.id,
            vendor_name=saved.vendor_name,
            evaluator_name=saved.evaluator_name,
            status=saved.status.value if saved.status else "",
            total_score=str(saved.total_score),
            rating=saved.rating.value if saved.rating else "",
        )


@dataclass
class CreateEvaluationCriteriaUseCase:
    """Use Case — ایجاد معیار ارزیابی."""
    criteria_repo: IEvaluationCriteriaRepository

    def execute(self, dto: CreateEvaluationCriteriaDTO, tenant_id=None) -> EvaluationCriteriaResponseDTO:
        criteria = EvaluationCriteria(
            id=uuid4(),
            tenant_id=tenant_id,
            criteria_code=dto.criteria_code,
            criteria_name=dto.criteria_name,
            description=dto.description,
            weight=Decimal(dto.weight),
            max_score=Decimal(dto.max_score),
        )

        saved = self.criteria_repo.save(criteria)

        return EvaluationCriteriaResponseDTO(
            id=saved.id,
            criteria_code=saved.criteria_code,
            criteria_name=saved.criteria_name,
            weight=str(saved.weight),
            max_score=str(saved.max_score),
            is_active=saved.is_active,
        )


@dataclass
class CreateEvaluationPeriodUseCase:
    """Use Case — ایجاد دوره ارزیابی."""
    period_repo: IEvaluationPeriodRepository

    def execute(self, dto: CreateEvaluationPeriodDTO, tenant_id=None) -> EvaluationPeriodResponseDTO:
        period = EvaluationPeriod(
            id=uuid4(),
            tenant_id=tenant_id,
            period_name=dto.period_name,
            start_date=dto.start_date,
            end_date=dto.end_date,
        )

        saved = self.period_repo.save(period)

        return EvaluationPeriodResponseDTO(
            id=saved.id,
            period_name=saved.period_name,
            start_date=saved.start_date,
            end_date=saved.end_date,
            is_active=saved.is_active,
        )
