from datetime import datetime
from typing import Optional

from transfers.eligibility.constants import EligibilityStatus
from transfers.eligibility.context import TransferEligibilityContext
from transfers.eligibility.result import EligibilityReason, EligibilityResult
from transfers.eligibility.rules import DEFAULT_RULES


class TransferEligibilityService:
    @classmethod
    def evaluate(
        cls,
        *,
        player,
        source_club,
        destination_club,
        window,
        is_international: bool = False,
        now: Optional[datetime] = None,
        current_transfer_id=None,
    ) -> EligibilityResult:
        context = TransferEligibilityContext(
            player=player,
            source_club=source_club,
            destination_club=destination_club,
            window=window,
            is_international=is_international,
            now=now,
            current_transfer_id=current_transfer_id,
        )

        reasons: list[EligibilityReason] = []
        for rule in DEFAULT_RULES:
            result = rule.evaluate(context)
            if result is not None:
                reasons.append(result)

        return cls._build_result(reasons)

    @staticmethod
    def _build_result(reasons: list[EligibilityReason]) -> EligibilityResult:
        if any(reason.status == EligibilityStatus.DENIED for reason in reasons):
            return EligibilityResult(
                status=EligibilityStatus.DENIED,
                reasons=tuple(reasons),
            )

        if any(
            reason.status == EligibilityStatus.REQUIRES_APPROVAL
            for reason in reasons
        ):
            return EligibilityResult(
                status=EligibilityStatus.REQUIRES_APPROVAL,
                reasons=tuple(reasons),
            )

        return EligibilityResult(
            status=EligibilityStatus.ALLOWED,
            reasons=tuple(),
        )
