"""CRM policies."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Protocol

from .enums import LeadState
from .entities import Lead, Stage
from .exceptions import InvalidTransitionError


class LeadStagePolicy(Protocol):
    def can_move(self, current: Stage, target: Stage, lead: Lead | None = None) -> bool: ...
    def ensure_movable(self, current: Stage, target: Stage, lead: Lead | None = None) -> None: ...


@dataclass(frozen=True)
class DefaultLeadStagePolicy:
    def can_move(self, current: Stage, target: Stage, lead: Lead | None = None) -> bool:
        if not isinstance(current, Stage) or not isinstance(target, Stage):
            raise TypeError("current and target must be Stage instances")
        if lead is not None and not isinstance(lead, Lead):
            raise TypeError("lead must be a Lead instance or None")
        if current == target:
            return True
        if current.is_terminal and not target.is_terminal:
            return False
        if lead is not None and lead.state in {LeadState.WON, LeadState.LOST} and not target.is_terminal:
            return False
        return target.sequence >= current.sequence or target.is_terminal

    def ensure_movable(self, current: Stage, target: Stage, lead: Lead | None = None) -> None:
        if not self.can_move(current, target, lead=lead):
            raise InvalidTransitionError(f"cannot move from {current.name} to {target.name}")
