"""
Metabolic Receipt Models for System Health

These receipts capture system metabolic health metrics:
- MetabolicSnapshotReceipt: Point-in-time health snapshot
- CoherenceMetabolismReceipt: ΔC drift tracking over time
- CalibrationReceipt: ECE and calibration metrics

---
feature:
  id: feature.metabolic_receipts
  name: Metabolic Receipt Models
  kind: module
  summary: Receipt models for ECE, ΔC drift, and latency metrics
  owners: ["@codex"]
  stage: experimental
  tags: [receipts, health, calibration, coherence]
  depends_on: [feature.receipt_writer, feature.metabolic_dashboard]
  invariants:
    - Every metabolic snapshot emits a receipt
    - ΔC drift beyond threshold triggers alert receipt
    - All health metrics are auditable
---
"""

from __future__ import annotations

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

from pydantic import Field

from receipts.base import BaseReceipt


class MetabolicStatus(str, Enum):
    """System health status levels."""
    HEALTHY = "healthy"
    WARN = "warn"
    CRITICAL = "critical"


class ECEMetrics(BaseReceipt):
    """
    Expected Calibration Error metrics.

    ECE measures how well model confidence matches actual accuracy.
    """

    model_config = {"frozen": True}

    receipt_type: str = Field(default="ECEMetrics", alias="type")

    ece_value: Optional[float] = Field(
        default=None,
        ge=0.0,
        le=1.0,
        description="Computed ECE value"
    )
    status: str = Field(
        default="healthy",
        description="Health status: healthy | warn | critical"
    )
    n_bins: int = Field(
        default=10,
        ge=1,
        description="Number of calibration bins"
    )
    total_samples: int = Field(
        default=0,
        ge=0,
        description="Total predictions evaluated"
    )
    warn_threshold: float = Field(
        default=0.05,
        ge=0.0,
        le=1.0,
        description="ECE warning threshold"
    )
    critical_threshold: float = Field(
        default=0.10,
        ge=0.0,
        le=1.0,
        description="ECE critical threshold"
    )

    # Per-bin breakdown
    bin_confidences: List[float] = Field(
        default_factory=list,
        description="Mean confidence per bin"
    )
    bin_accuracies: List[float] = Field(
        default_factory=list,
        description="Observed accuracy per bin"
    )
    bin_counts: List[int] = Field(
        default_factory=list,
        description="Sample count per bin"
    )


class DeltaCMetrics(BaseReceipt):
    """
    Coherence Drift (ΔC) metrics.

    Tracks coherence delta over time to detect model drift.
    """

    model_config = {"frozen": True}

    receipt_type: str = Field(default="DeltaCMetrics", alias="type")

    delta_c: Optional[float] = Field(
        default=None,
        description="Current coherence drift from baseline"
    )
    baseline_coherence: Optional[float] = Field(
        default=None,
        ge=0.0,
        le=1.0,
        description="Baseline coherence value"
    )
    current_coherence: Optional[float] = Field(
        default=None,
        ge=0.0,
        le=1.0,
        description="Current coherence value"
    )
    status: str = Field(
        default="healthy",
        description="Health status: healthy | warn | critical"
    )
    samples: int = Field(
        default=0,
        ge=0,
        description="Number of coherence samples"
    )
    warn_threshold: float = Field(
        default=-0.05,
        le=0.0,
        description="ΔC warning threshold (negative = decline)"
    )
    critical_threshold: float = Field(
        default=-0.10,
        le=0.0,
        description="ΔC critical threshold"
    )
    window_seconds: float = Field(
        default=300.0,
        ge=0.0,
        description="Rolling window duration in seconds"
    )


class LatencyMetrics(BaseReceipt):
    """
    Latency performance metrics.

    Tracks p50, p95, and mean latency.
    """

    model_config = {"frozen": True}

    receipt_type: str = Field(default="LatencyMetrics", alias="type")

    p95_ms: Optional[float] = Field(
        default=None,
        ge=0.0,
        description="p95 latency in milliseconds"
    )
    p50_ms: Optional[float] = Field(
        default=None,
        ge=0.0,
        description="p50 (median) latency in milliseconds"
    )
    mean_ms: Optional[float] = Field(
        default=None,
        ge=0.0,
        description="Mean latency in milliseconds"
    )
    status: str = Field(
        default="healthy",
        description="Health status: healthy | warn | critical"
    )
    samples: int = Field(
        default=0,
        ge=0,
        description="Number of latency samples"
    )
    warn_threshold_ms: float = Field(
        default=500.0,
        ge=0.0,
        description="p95 warning threshold in ms"
    )
    critical_threshold_ms: float = Field(
        default=2000.0,
        ge=0.0,
        description="p95 critical threshold in ms"
    )


class MetabolicSnapshotReceipt(BaseReceipt):
    """
    Point-in-time snapshot of system metabolic health.

    Emitted periodically to provide audit trail of system health.
    """

    receipt_type: str = Field(default="MetabolicSnapshotReceipt", alias="type")
    domain: str = Field(default="metabolic")

    # Aggregate status
    overall_status: str = Field(
        default="healthy",
        description="Overall health: healthy | warn | critical"
    )

    # Individual metrics
    ece: Dict[str, Any] = Field(
        default_factory=dict,
        description="ECE calibration metrics"
    )
    delta_c: Dict[str, Any] = Field(
        default_factory=dict,
        description="Coherence drift metrics"
    )
    latency: Dict[str, Any] = Field(
        default_factory=dict,
        description="Latency performance metrics"
    )

    # Window configuration
    window_start: Optional[str] = Field(
        default=None,
        description="ISO timestamp of window start"
    )
    window_end: Optional[str] = Field(
        default=None,
        description="ISO timestamp of window end"
    )

    # Alerts triggered
    alerts: List[str] = Field(
        default_factory=list,
        description="List of triggered alert codes"
    )
    alert_details: Dict[str, Any] = Field(
        default_factory=dict,
        description="Detailed alert information"
    )


class CoherenceMetabolismReceipt(BaseReceipt):
    """
    Receipt tracking coherence metabolism over time.

    Used to detect gradual coherence degradation that might
    indicate model drift or data quality issues.
    """

    receipt_type: str = Field(default="CoherenceMetabolismReceipt", alias="type")
    domain: str = Field(default="metabolic")

    # Time series data
    window_start: str = Field(description="ISO timestamp of window start")
    window_end: str = Field(description="ISO timestamp of window end")

    # Coherence trajectory
    coherence_baseline: float = Field(
        ge=0.0,
        le=1.0,
        description="Baseline coherence at window start"
    )
    coherence_current: float = Field(
        ge=0.0,
        le=1.0,
        description="Current coherence at window end"
    )
    delta_c: float = Field(
        description="Change in coherence (current - baseline)"
    )

    # Trend analysis
    trend_direction: str = Field(
        default="stable",
        description="Trend: improving | stable | declining"
    )
    trend_magnitude: float = Field(
        default=0.0,
        description="Magnitude of trend (absolute value)"
    )
    trend_confidence: float = Field(
        default=0.0,
        ge=0.0,
        le=1.0,
        description="Confidence in trend detection"
    )

    # Statistical details
    samples_in_window: int = Field(
        ge=0,
        description="Number of coherence samples in window"
    )
    std_deviation: Optional[float] = Field(
        default=None,
        ge=0.0,
        description="Standard deviation of coherence values"
    )

    # Alert status
    alert_triggered: bool = Field(
        default=False,
        description="Whether this drift triggered an alert"
    )
    alert_code: Optional[str] = Field(
        default=None,
        description="Alert code if triggered"
    )


class CalibrationReceipt(BaseReceipt):
    """
    Receipt for model calibration audit.

    Emitted when calibration metrics are evaluated, providing
    a court-ready record of model reliability.
    """

    receipt_type: str = Field(default="CalibrationReceipt", alias="type")
    domain: str = Field(default="metabolic")

    # Model identification
    model_id: str = Field(description="Identifier of calibrated model")
    model_version: Optional[str] = Field(
        default=None,
        description="Version of the model"
    )

    # ECE metrics
    ece: float = Field(
        ge=0.0,
        le=1.0,
        description="Expected Calibration Error"
    )
    ece_status: str = Field(
        default="healthy",
        description="ECE status: healthy | warn | critical"
    )

    # Per-bin calibration
    n_bins: int = Field(
        default=10,
        ge=1,
        description="Number of calibration bins"
    )
    bin_data: List[Dict[str, Any]] = Field(
        default_factory=list,
        description="Per-bin calibration data"
    )

    # Sample statistics
    total_predictions: int = Field(
        ge=0,
        description="Total predictions evaluated"
    )
    evaluation_window: str = Field(
        description="Time window of evaluation (e.g., '24h')"
    )

    # Compliance
    meets_threshold: bool = Field(
        default=True,
        description="Whether calibration meets acceptable threshold"
    )
    threshold_used: float = Field(
        ge=0.0,
        le=1.0,
        description="ECE threshold applied"
    )


class MeaningMetricsReceipt(BaseReceipt):
    """
    Receipt capturing meaning-level metrics.

    Based on Semantic Physics framework:
    - Meaning = Compression Gap
    - Coherence = Conservation of meaning
    - Energy = Computational cost of understanding
    """

    receipt_type: str = Field(default="MeaningMetricsReceipt", alias="type")
    domain: str = Field(default="metabolic")

    # Compression gap (meaning)
    compression_ratio: float = Field(
        ge=0.0,
        description="Ratio of compressed to raw representation"
    )
    compression_gap: float = Field(
        description="Gap between achievable and actual compression"
    )

    # Coherence conservation
    coherence_in: float = Field(
        ge=0.0,
        le=1.0,
        description="Input coherence"
    )
    coherence_out: float = Field(
        ge=0.0,
        le=1.0,
        description="Output coherence"
    )
    delta_c: float = Field(
        description="Change in coherence (conservation measure)"
    )

    # Energy metrics
    energy_spent: float = Field(
        ge=0.0,
        description="Computational energy (tokens, FLOPS, etc.)"
    )
    energy_efficiency: float = Field(
        ge=0.0,
        description="Meaning per unit energy"
    )

    # Phase state
    phase: str = Field(
        default="exploration",
        description="Current phase: exploration | exploitation | crystallization"
    )

    # Context
    operation: str = Field(
        description="Operation that generated these metrics"
    )
    context_depth: int = Field(
        default=0,
        ge=0,
        description="Depth of context used"
    )


__all__ = [
    "MetabolicStatus",
    "ECEMetrics",
    "DeltaCMetrics",
    "LatencyMetrics",
    "MetabolicSnapshotReceipt",
    "CoherenceMetabolismReceipt",
    "CalibrationReceipt",
    "MeaningMetricsReceipt",
]
