"""Neutral preprocessing-set helpers for Kamil ADC acquisition."""

from __future__ import annotations

import time

import numpy as np

from python_app.models.dataset_model import ComboKey, SweepCollection, TraceData
from python_app.models.run_config_model import ComboModel, RunConfigModel


def build_kamil_adc_neutral_s21_sets(
    config: RunConfigModel,
    point_count: int,
) -> tuple[SweepCollection, SweepCollection]:
    """Build S21 calibration/reference collections that leave input S21 unchanged."""
    if not config.is_kamil_adc:
        raise ValueError("Neutral Kamil ADC sets require radar.model='kamil_adc'")

    points = int(point_count)
    if points <= 0:
        raise ValueError("Kamil ADC neutral set point count must be > 0")

    combos = list(config.combos)
    if not combos:
        combos = RunConfigModel.build_full_combos(config.input_switch.positions, config.output_switch.positions)
    if not combos:
        raise ValueError("Kamil ADC neutral sets require at least one switch combo")

    frequency_hz = np.linspace(
        float(config.radar.sweep.start_hz),
        float(config.radar.sweep.stop_hz),
        points,
        dtype=np.float32,
    )
    now_ns = time.monotonic_ns()
    calibration = _neutral_collection(
        combos=combos,
        frequency_hz=frequency_hz,
        s21_value=np.complex64(1.0 + 0.0j),
        monotonic_ns=now_ns,
    )
    reference = _neutral_collection(
        combos=combos,
        frequency_hz=frequency_hz,
        s21_value=np.complex64(0.0 + 0.0j),
        monotonic_ns=now_ns,
    )
    return calibration, reference


def _neutral_collection(
    *,
    combos: list[ComboModel],
    frequency_hz: np.ndarray,
    s21_value: np.complex64,
    monotonic_ns: int,
) -> SweepCollection:
    traces = []
    for combo in combos:
        point_count = int(frequency_hz.size)
        traces.append(
            TraceData(
                combo=ComboKey(input=int(combo.input), output=int(combo.output)),
                frequency_hz=frequency_hz.copy(),
                s11=np.zeros(point_count, dtype=np.complex64),
                s21=np.full(point_count, s21_value, dtype=np.complex64),
            )
        )
    return SweepCollection(
        collection_id=1,
        monotonic_ns=monotonic_ns,
        traces=traces,
        capture_start_ns=monotonic_ns,
        capture_end_ns=monotonic_ns,
    )
