"""Tests for RadioState and ReceiverState dataclasses."""

from __future__ import annotations

import pytest

from icom_lan.radio_state import RadioState, ReceiverState


# ---------------------------------------------------------------------------
# ReceiverState defaults
# ---------------------------------------------------------------------------


def test_receiver_state_defaults() -> None:
    rx = ReceiverState()
    assert rx.freq == 0
    assert rx.mode == "USB"
    assert rx.filter is None
    assert rx.data_mode is False
    assert rx.att == 0
    assert rx.preamp == 0
    assert rx.nb is False
    assert rx.nr is False
    assert rx.digisel is False
    assert rx.ipplus is False
    assert rx.af_level == 0
    assert rx.rf_gain == 0
    assert rx.squelch == 0
    assert rx.s_meter == 0


def test_receiver_state_field_update() -> None:
    rx = ReceiverState()
    rx.freq = 14_074_000
    rx.mode = "USB"
    rx.filter = 2
    rx.att = 18
    rx.preamp = 1
    rx.nb = True
    rx.s_meter = 120
    assert rx.freq == 14_074_000
    assert rx.filter == 2
    assert rx.att == 18
    assert rx.preamp == 1
    assert rx.nb is True
    assert rx.s_meter == 120


# ---------------------------------------------------------------------------
# RadioState defaults
# ---------------------------------------------------------------------------


def test_radio_state_defaults() -> None:
    rs = RadioState()
    assert rs.active == "MAIN"
    assert rs.ptt is False
    assert rs.power_level == 0
    assert rs.split is False
    assert isinstance(rs.main, ReceiverState)
    assert isinstance(rs.sub, ReceiverState)


def test_radio_state_main_sub_are_independent() -> None:
    rs = RadioState()
    rs.main.freq = 14_074_000
    rs.sub.freq = 7_000_000
    assert rs.main.freq == 14_074_000
    assert rs.sub.freq == 7_000_000


# ---------------------------------------------------------------------------
# receiver() method
# ---------------------------------------------------------------------------


def test_receiver_main_returns_main() -> None:
    rs = RadioState()
    rs.main.freq = 14_000_000
    assert rs.receiver("MAIN") is rs.main
    assert rs.receiver("MAIN").freq == 14_000_000


def test_receiver_sub_returns_sub() -> None:
    rs = RadioState()
    rs.sub.freq = 7_000_000
    assert rs.receiver("SUB") is rs.sub
    assert rs.receiver("SUB").freq == 7_000_000


def test_receiver_unknown_falls_back_to_sub() -> None:
    # Any non-"MAIN" string returns sub (matches the ternary logic)
    rs = RadioState()
    assert rs.receiver("OTHER") is rs.sub


# ---------------------------------------------------------------------------
# to_dict()
# ---------------------------------------------------------------------------


def test_to_dict_structure() -> None:
    rs = RadioState()
    d = rs.to_dict()
    assert set(d.keys()) == {"active", "ptt", "power_level", "split", "main", "sub"}
    assert d["active"] == "MAIN"
    assert d["ptt"] is False
    assert d["power_level"] == 0
    assert d["split"] is False


def test_to_dict_main_keys() -> None:
    rs = RadioState()
    main = rs.to_dict()["main"]
    expected_keys = {
        "freq", "mode", "filter", "data_mode",
        "att", "preamp", "nb", "nr", "digisel", "ipplus",
        "af_level", "rf_gain", "squelch", "s_meter",
    }
    assert set(main.keys()) == expected_keys


def test_to_dict_reflects_field_changes() -> None:
    rs = RadioState()
    rs.main.freq = 14_074_000
    rs.main.mode = "USB"
    rs.main.att = 18
    rs.ptt = True
    rs.split = True
    d = rs.to_dict()
    assert d["ptt"] is True
    assert d["split"] is True
    assert d["main"]["freq"] == 14_074_000
    assert d["main"]["att"] == 18


def test_to_dict_sub_independent() -> None:
    rs = RadioState()
    rs.main.freq = 14_000_000
    rs.sub.freq = 7_000_000
    d = rs.to_dict()
    assert d["main"]["freq"] == 14_000_000
    assert d["sub"]["freq"] == 7_000_000


def test_to_dict_is_json_serialisable() -> None:
    import json
    rs = RadioState()
    rs.main.freq = 14_074_000
    rs.main.nb = True
    rs.ptt = False
    payload = json.dumps(rs.to_dict())
    reloaded = json.loads(payload)
    assert reloaded["main"]["freq"] == 14_074_000
    assert reloaded["main"]["nb"] is True
