"""Smoke tests for `openrun.plots`.

We deliberately don't visual-regress matplotlib output — see ROADMAP test
conventions. Each test asserts only structural properties: bar count, axis
labels, "no data" sentinel behavior.
"""

from __future__ import annotations

import matplotlib

matplotlib.use("Agg")  # must be set before pyplot import

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from openrun.plots import plot_fit_decoupling


def _synthetic_records(duration_s: int = 1800, decel_at: int = 900) -> pd.DataFrame:
    """A FIT-records-like frame: constant HR, but speed drops halfway through.
    With 2 segments, the second-half efficiency must be lower → positive decoupling.
    """
    elapsed = np.arange(duration_s, dtype=float)
    speed = np.where(elapsed < decel_at, 3.0, 2.5)
    hr = np.full(duration_s, 150.0)
    return pd.DataFrame({"elapsed_s": elapsed, "speed_mps": speed, "heart_rate": hr})


def test_plot_fit_decoupling_returns_axes_with_n_bars() -> None:
    records = _synthetic_records()
    ax = plot_fit_decoupling(records, segments=4)

    bars = [p for p in ax.patches if hasattr(p, "get_height")]
    assert len(bars) == 4
    assert ax.get_ylabel() == "decoupling (%)"
    plt.close(ax.figure)


def test_plot_fit_decoupling_segments_default_is_two() -> None:
    records = _synthetic_records()
    ax = plot_fit_decoupling(records)
    bars = [p for p in ax.patches if hasattr(p, "get_height")]
    assert len(bars) == 2
    plt.close(ax.figure)


def test_plot_fit_decoupling_handles_empty_records() -> None:
    """Empty records frame → 'no usable records' sentinel, not a crash."""
    empty = pd.DataFrame(columns=["elapsed_s", "speed_mps", "heart_rate"])
    ax = plot_fit_decoupling(empty)
    texts = [t.get_text() for t in ax.texts]
    assert any("no usable records" in t for t in texts)
    plt.close(ax.figure)


def test_plot_fit_decoupling_respects_caller_axes() -> None:
    """When the caller passes ax=, no new figure is created."""
    fig, ax = plt.subplots()
    out = plot_fit_decoupling(_synthetic_records(), ax=ax)
    assert out is ax
    plt.close(fig)
