"""System status domain models."""

from __future__ import annotations

from pydantic import BaseModel, ConfigDict

from radiens_core.models.enums import (
    BackboneMode,
    DataRecordingType,
    Port,
    RecordMode,
    StimKeypressIndex,
    StimStep,
    StreamMode,
    TriggerChannel,
)
from radiens_core.models.gpio import GPIOChannelCount
from radiens_core.models.ports import PortChannelCount


class RestartRequest(BaseModel):
    """Request to restart the system with a specific backbone mode."""

    model_config = ConfigDict(frozen=True)

    mode: BackboneMode


class RecordStateRequest(BaseModel):
    """Request to change recording state."""

    model_config = ConfigDict(frozen=True)

    mode: RecordMode
    port: Port | None = None  # If None, system-level record control


class StreamStateRequest(BaseModel):
    """Request to change streaming state."""

    model_config = ConfigDict(frozen=True)

    mode: StreamMode


class StreamingStatus(BaseModel):
    """Current streaming status."""

    model_config = ConfigDict(frozen=True)

    stream_mode: StreamMode
    primary_cache_t_range: list[float]
    hardware_memory_level: float


class RecordingStatus(BaseModel):
    """Current recording status."""

    model_config = ConfigDict(frozen=True)

    record_mode: RecordMode
    active_filename: str
    duration: float
    error: str
    record_mode_port_a: RecordMode | None = None
    record_mode_port_b: RecordMode | None = None
    record_mode_port_c: RecordMode | None = None
    record_mode_port_d: RecordMode | None = None
    record_mode_port_e: RecordMode | None = None
    record_mode_port_f: RecordMode | None = None
    record_mode_port_g: RecordMode | None = None
    record_mode_port_h: RecordMode | None = None


class RecordingConfig(BaseModel):
    """Recording configuration settings.

    Configures output file paths, naming, and recording behavior.
    Used as both request (for set_recording_config) and response (for get_recording_config).
    """

    model_config = ConfigDict(frozen=True)

    base_file_name: str
    """Base filename for recording output (without extension or timestamp)."""

    base_file_path: str
    """Base directory path for recording files."""

    datasource_idx: int = 0
    """Index number for the composed file name."""

    time_stamp: bool = True
    """True to include timestamp in the composed file name."""

    split_files_by_port: bool = False
    """True to create separate files for each port."""

    force_start_at_tstamp_0: bool = False
    """True to force recording to start at timestamp 0."""

    recording_type: DataRecordingType = DataRecordingType.CONTINUOUS
    """Type of data to record (continuous, spikes, or both)."""


class BackboneStatus(BaseModel):
    """Complete system backbone status."""

    model_config = ConfigDict(frozen=True)

    streaming: StreamingStatus
    recording: RecordingStatus
    ports: list[PortChannelCount]
    is_connected: bool
    gpio_channel_count: GPIOChannelCount


class SetTriggerStateRequest(BaseModel):
    """Request to set trigger channel state.

    Configures which trigger channels are enabled for stimulation.
    """

    model_config = ConfigDict(frozen=True)

    channel: TriggerChannel
    enabled: bool
    port: Port


class TriggerState(BaseModel):
    """Current trigger channel configuration.

    Shows which channels and ports are currently enabled for triggering.
    """

    model_config = ConfigDict(frozen=True)

    enabled_channels: list[TriggerChannel]
    ports: list[Port]


class ManualStimTriggerRequest(BaseModel):
    """Request for manual stimulation trigger.

    Allows direct control of stimulation triggering.
    """

    model_config = ConfigDict(frozen=True)

    trigger: StimKeypressIndex
    """Keypress trigger (1-8). Matches ``StimParams.trigger_source_idx``."""
    trigger_on: bool


class ManualStimTriggerToggleRequest(BaseModel):
    """Request to toggle manual stimulation trigger.

    Convenient toggle interface for stimulation control.
    """

    model_config = ConfigDict(frozen=True)

    trigger: StimKeypressIndex
    """Keypress trigger (1-8). Matches ``StimParams.trigger_source_idx``."""


class StimStepRequest(BaseModel):
    """Request to set stimulation step size.

    Configures the current increment/decrement granularity.
    """

    model_config = ConfigDict(frozen=True)

    stim_step: StimStep


class StimStepState(BaseModel):
    """Current stimulation step size setting.

    Shows the current stimulation step configuration.
    """

    model_config = ConfigDict(frozen=True)

    stim_step: StimStep
