"""Data models for sweep and processing payload collections."""

from __future__ import annotations

from dataclasses import dataclass, field

import numpy as np


def _empty_f32_array() -> np.ndarray:
    """Return empty float32 array used by payload defaults."""
    return np.array([], dtype=np.float32)


def _empty_c64_array() -> np.ndarray:
    """Return empty complex64 array used by payload defaults."""
    return np.array([], dtype=np.complex64)


def _empty_f32_matrix() -> np.ndarray:
    """Return empty 2D float32 matrix used by payload defaults."""
    return np.zeros((0, 0), dtype=np.float32)


@dataclass(frozen=True, slots=True)
class ComboKey:
    """Switch combination key: input position + output position."""

    input_pos: int
    output_pos: int


@dataclass(slots=True)
class TraceData:
    """One frequency-domain S21 trace for a specific switch combination."""

    combo: ComboKey
    frequency_hz: np.ndarray
    s21: np.ndarray


@dataclass(slots=True)
class SweepCollection:
    """Raw or preprocessed collection containing multiple combo traces."""

    collection_id: int
    monotonic_ns: int
    traces: list[TraceData] = field(default_factory=list)


@dataclass(slots=True)
class ResultPayload:
    """Processed payload item (trace-like or scalar) produced by processor stage."""

    processing_name: str
    kind: int
    frequency_hz: np.ndarray = field(default_factory=_empty_f32_array)
    trace: np.ndarray = field(default_factory=_empty_c64_array)
    scalar_value: float = 0.0
    image_x_axis: np.ndarray = field(default_factory=_empty_f32_array)
    image_y_axis: np.ndarray = field(default_factory=_empty_f32_array)
    image: np.ndarray = field(default_factory=_empty_f32_matrix)
    table: np.ndarray = field(default_factory=_empty_f32_matrix)


@dataclass(slots=True)
class ResultBlock:
    """Result payload block grouped by one switch combination."""

    combo: ComboKey
    payloads: list[ResultPayload] = field(default_factory=list)


@dataclass(slots=True)
class ResultCollection:
    """Collection of processed payload blocks for one acquisition cycle."""

    collection_id: int
    monotonic_ns: int
    collection_payloads: list[ResultPayload] = field(default_factory=list)
    blocks: list[ResultBlock] = field(default_factory=list)
