"""Pharmacy validators — Phase 13.6."""
from __future__ import annotations

from app.models.types import PrescriptionLifecycleAction, PrescriptionOrderStatus
from shared.exceptions import AppError

ALLOWED: dict[PrescriptionLifecycleAction, set[PrescriptionOrderStatus]] = {
    PrescriptionLifecycleAction.SUBMIT: set(),
    PrescriptionLifecycleAction.ACCEPT: {PrescriptionOrderStatus.SUBMITTED},
    PrescriptionLifecycleAction.PREPARE: {PrescriptionOrderStatus.ACCEPTED},
    PrescriptionLifecycleAction.MARK_READY: {PrescriptionOrderStatus.PREPARING},
    PrescriptionLifecycleAction.COMPLETE_PICKUP: {PrescriptionOrderStatus.READY},
    PrescriptionLifecycleAction.CANCEL: {
        PrescriptionOrderStatus.SUBMITTED,
        PrescriptionOrderStatus.ACCEPTED,
        PrescriptionOrderStatus.PREPARING,
        PrescriptionOrderStatus.READY,
    },
}
TARGET: dict[PrescriptionLifecycleAction, PrescriptionOrderStatus] = {
    PrescriptionLifecycleAction.SUBMIT: PrescriptionOrderStatus.SUBMITTED,
    PrescriptionLifecycleAction.ACCEPT: PrescriptionOrderStatus.ACCEPTED,
    PrescriptionLifecycleAction.PREPARE: PrescriptionOrderStatus.PREPARING,
    PrescriptionLifecycleAction.MARK_READY: PrescriptionOrderStatus.READY,
    PrescriptionLifecycleAction.COMPLETE_PICKUP: PrescriptionOrderStatus.PICKED_UP,
    PrescriptionLifecycleAction.CANCEL: PrescriptionOrderStatus.CANCELLED,
}
TERMINAL = frozenset({PrescriptionOrderStatus.PICKED_UP, PrescriptionOrderStatus.CANCELLED})


def ensure_prescription_transition(
    *, action: PrescriptionLifecycleAction, current: PrescriptionOrderStatus
) -> None:
    if current in TERMINAL:
        raise AppError("سفارش نسخه در وضعیت پایانی است", status_code=409, error_code="prescription_terminal")
    allowed = ALLOWED.get(action, set())
    if action != PrescriptionLifecycleAction.SUBMIT and current not in allowed:
        raise AppError(
            "انتقال وضعیت نسخه مجاز نیست",
            status_code=409,
            error_code="invalid_prescription_transition",
        )


def target_prescription_status(action: PrescriptionLifecycleAction) -> PrescriptionOrderStatus:
    return TARGET[action]
