"""Sales policies."""

from __future__ import annotations

from dataclasses import dataclass
from typing import Protocol

from .enums import SalesOrderState
from .exceptions import InvalidSalesTransitionError


class SalesOrderTransitionPolicy(Protocol):
    def can_transition(self, current: SalesOrderState, target: SalesOrderState) -> bool: ...
    def ensure_transition(self, current: SalesOrderState, target: SalesOrderState) -> None: ...


@dataclass(frozen=True)
class DefaultSalesOrderTransitionPolicy:
    def can_transition(self, current: SalesOrderState, target: SalesOrderState) -> bool:
        if not isinstance(current, SalesOrderState) or not isinstance(target, SalesOrderState):
            raise TypeError("current and target must be SalesOrderState instances")
        if current == target:
            return True
        if current in {SalesOrderState.DONE, SalesOrderState.CANCELLED}:
            return False
        if target == SalesOrderState.CANCELLED:
            return True
        if current == SalesOrderState.QUOTATION and target in {SalesOrderState.SENT, SalesOrderState.SALE}:
            return True
        if current == SalesOrderState.SENT and target == SalesOrderState.SALE:
            return True
        if current == SalesOrderState.SALE and target == SalesOrderState.DONE:
            return True
        return False

    def ensure_transition(self, current: SalesOrderState, target: SalesOrderState) -> None:
        if not self.can_transition(current, target):
            raise InvalidSalesTransitionError(f"cannot move from {current.value} to {target.value}")
