"""Base types for injury criteria calculations."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Protocol, runtime_checkable

from impakt.channel.model import Channel, DummyInfo


@dataclass(frozen=True)
class CriterionResult:
    """Result of an injury criterion computation.

    Attributes:
        criterion: Name of the criterion (e.g., 'HIC15').
        value: Computed value.
        unit: Unit of the value (dimensionless for indices).
        time_of_peak: Time at which the peak/critical value occurs.
        window: (t1, t2) time window for window-based criteria (HIC).
        body_region: Body region this criterion applies to.
        details: Additional computation details.
    """

    criterion: str
    value: float
    unit: str = ""
    time_of_peak: float | None = None
    window: tuple[float, float] | None = None
    body_region: str = ""
    details: dict[str, Any] = field(default_factory=dict)

    def __repr__(self) -> str:
        unit_str = f" {self.unit}" if self.unit else ""
        return f"CriterionResult({self.criterion}={self.value:.2f}{unit_str})"


@runtime_checkable
class InjuryCriterion(Protocol):
    """Protocol for injury criteria calculators."""

    @property
    def name(self) -> str:
        """Criterion name (e.g., 'HIC15', 'Nij')."""
        ...

    @property
    def required_channels(self) -> list[str]:
        """Channel patterns required for computation."""
        ...

    def compute(
        self,
        channels: dict[str, Channel],
        dummy: DummyInfo | None = None,
    ) -> CriterionResult:
        """Compute the criterion from the given channels."""
        ...
