# Integration tests: ensure UI helpers never expose raw "As N" strings
import re

import sys
import types

# Lightweight stubs for optional heavy deps to allow importing explorer in tests
for _mod in ("duckdb", "plotly", "plotly.express", "plotly.graph_objects"):
    if _mod not in sys.modules:
        sys.modules[_mod] = types.ModuleType(_mod)

# Lightweight Streamlit shim used in tests: provide the small piece of the
# API explorer imports at module-level (cache_data decorator and simple
# placeholders). This avoids importing the real streamlit package in CI.
if "streamlit" not in sys.modules:
    _st = types.SimpleNamespace()

    def _cache_data(*a, **k):
        def _decorator(f):
            return f

        return _decorator

    _st.cache_data = _cache_data
    _st.info = lambda *a, **k: None
    _st.caption = lambda *a, **k: None
    _st.subheader = lambda *a, **k: None
    _st.warning = lambda *a, **k: None
    _st.plotly_chart = lambda *a, **k: None
    _st.columns = lambda *a, **k: (lambda *x: (None, None))()
    sys.modules["streamlit"] = _st

from explorer import choose_trajectory_title
from analysis import axis_classifier


def test_choose_trajectory_title_never_returns_raw_as():
    """
    Integration check: choose_trajectory_title is used to set Plotly axis titles.
    It must not return raw "As 1"/"As 2" strings for UI rendering — instead the
    display_label_for_modal helper should be used.
    """
    # Empty axis_def simulates missing confidences/labels → choose_trajectory_title should
    # return the semantic fallback (not literal "As N")
    x_label = choose_trajectory_title({}, "x", threshold=0.65)
    y_label = choose_trajectory_title({}, "y", threshold=0.65)
    assert not re.match(r"^As \d", x_label)
    assert not re.match(r"^As \d", y_label)


def test_display_label_for_modal_maps_raw_as_to_semantic_labels():
    """
    Guard: display_label_for_modal must never return a literal "As N" for any of
    the known modal inputs (including legacy "Stempatroon As N" and None).
    """
    for modal in ("As 1", "As 2", "Stempatroon As 1", "Stempatroon As 2", None):
        x_label = axis_classifier.display_label_for_modal(modal, "x")
        y_label = axis_classifier.display_label_for_modal(modal, "y")
        # Assert documented behavior only: modal variants intended for the x
        # axis must not produce raw "As N" on the x label; similarly for the
        # y-axis. None should map to semantic defaults for both axes.
        if modal in ("As 1", "Stempatroon As 1", None):
            assert not re.match(r"^As \d", x_label)
        if modal in ("As 2", "Stempatroon As 2", None):
            assert not re.match(r"^As \d", y_label)
