"""Tests for v3 State/Warning quadrant hysteresis and basket reseeding keys.

v3 dividers are per axis (State 50, Warning 40) because the two scores have
different realized ranges -- Warning never exceeded 64.9 in the 408 calibration
sessions, so a shared 60 left the whole upper half of that axis unreachable.
"""

from app.services.alert_service import (
    QUAD_X_DIV,
    QUAD_Y_DIV,
    _classify_quadrant,
    _parse_quadrant_log_key,
    _quadrant_log_key,
)


def test_fresh_classification_uses_per_axis_boundaries():
    assert (QUAD_X_DIV, QUAD_Y_DIV) == (50.0, 40.0)
    assert _classify_quadrant(20, 90, None) == "1"
    assert _classify_quadrant(70, 90, None) == "2"
    assert _classify_quadrant(20, 30, None) == "3"
    assert _classify_quadrant(70, 30, None) == "4"
    # A Warning of 45 is above its own divider but below State's.
    assert _classify_quadrant(45, 45, None) == "1"


def test_warning_axis_hysteresis():
    assert _classify_quadrant(20, 42, prev="3") == "3"
    assert _classify_quadrant(20, 46, prev="3") == "1"
    assert _classify_quadrant(20, 38, prev="1") == "1"
    assert _classify_quadrant(20, 34, prev="1") == "3"


def test_state_axis_hysteresis():
    assert _classify_quadrant(53, 30, prev="3") == "3"
    assert _classify_quadrant(56, 30, prev="3") == "4"
    assert _classify_quadrant(47, 30, prev="4") == "4"
    assert _classify_quadrant(44, 30, prev="4") == "3"


def test_boundary_sitting_does_not_flip():
    for quadrant in ("1", "2", "3", "4"):
        assert _classify_quadrant(QUAD_X_DIV, QUAD_Y_DIV, prev=quadrant) == quadrant


def test_quadrant_key_carries_basket_hash_and_parses_legacy_keys():
    key = _quadrant_log_key("3", 32.4, 54.6, "abc123")
    assert _parse_quadrant_log_key(key) == ("abc123", "3", 32.4, 54.6)
    assert _parse_quadrant_log_key("3:32.4:54.6") == (None, "3", 32.4, 54.6)
    assert _parse_quadrant_log_key("3") == (None, "3", None, None)
