"""
OrganismState transition receipt.

Records transitions in the canonical organism state machine so dashboards and
auditors can track regime changes (normal/elevated/critical/etc.).
"""

from __future__ import annotations

from datetime import datetime, timezone
from enum import Enum
from typing import Any, Dict, List, Optional

from receipts.base import BaseReceipt, Domain
from receipts.compat.pyd import Field


class OrganismState(str, Enum):
    NORMAL = "normal"
    ELEVATED_TENSION = "elevated_tension"
    CRITICAL = "critical"
    FROZEN = "frozen"
    RECOVERY = "recovery"
    DEGRADED = "degraded"
    LABS_MODE = "labs_mode"
    CLINICAL_STRICT = "clinical_strict"
    SAFE_MODE = "safe_mode"


class OrganismStateTransitionReceipt(BaseReceipt):
    """Receipt emitted when organism state transitions."""

    receipt_type: str = Field(default="OrganismStateTransitionReceipt", alias="type")
    domain: str = Field(default=Domain.GOVERNANCE.value)

    prev_state: OrganismState = Field(..., description="State before transition")
    next_state: OrganismState = Field(..., description="State after transition")
    triggers: List[str] = Field(default_factory=list, description="Triggers that caused the transition")
    advisory: bool = Field(default=False, description="True if transition is advisory-only")

    snapshot: Dict[str, Any] = Field(
        default_factory=dict,
        description="Telemetry snapshot at transition (delta_c, omega_h, load, etc.)",
    )

    envelope_id: Optional[str] = Field(default=None, description="Decision envelope id (if applicable)")
    case_id: Optional[str] = Field(default=None, description="Case/session identifier")
    profile: Optional[str] = Field(default=None, description="Active profile at transition")

    @staticmethod
    def now_iso() -> str:
        return datetime.now(timezone.utc).isoformat()

    @classmethod
    def from_transition(
        cls,
        prev_state: OrganismState,
        next_state: OrganismState,
        triggers: List[str],
        snapshot: Dict[str, Any],
        advisory: bool = False,
        envelope_id: Optional[str] = None,
        case_id: Optional[str] = None,
        profile: Optional[str] = None,
        parent_ids: Optional[List[str]] = None,
    ) -> "OrganismStateTransitionReceipt":
        """Factory to build a transition receipt."""
        return cls(
            receipt_id=f"org_state_{cls.now_iso()}",
            prev_state=prev_state,
            next_state=next_state,
            triggers=triggers,
            snapshot=snapshot,
            advisory=advisory,
            envelope_id=envelope_id,
            case_id=case_id,
            profile=profile,
            parent_ids=parent_ids or [],
        )
