from __future__ import annotations

import pandas as pd

from web_core.charting import _missing_calendar_day_values, build_figure
from web_core.constants import TREND_NEUTRAL


def _make_daily_df(days: list[str]) -> pd.DataFrame:
    index = pd.DatetimeIndex([pd.Timestamp(day, tz="UTC") for day in days])
    count = len(index)
    return pd.DataFrame(
        {
            "Open": [100 + i for i in range(count)],
            "High": [101 + i for i in range(count)],
            "Low": [99 + i for i in range(count)],
            "Close": [100.5 + i for i in range(count)],
            "Volume": [1000 + i for i in range(count)],
            "classification": ["fake"] * count,
            "trend_state": [TREND_NEUTRAL] * count,
        },
        index=index,
    )


def _make_intraday_df(days: list[str]) -> pd.DataFrame:
    index_values: list[pd.Timestamp] = []
    for day in days:
        session = pd.date_range(
            start=f"{day} 09:30:00",
            end=f"{day} 15:45:00",
            freq="15min",
            tz="America/New_York",
        )
        index_values.extend(session.to_list())

    index = pd.DatetimeIndex(index_values)
    count = len(index)
    return pd.DataFrame(
        {
            "Open": [100 + i for i in range(count)],
            "High": [101 + i for i in range(count)],
            "Low": [99 + i for i in range(count)],
            "Close": [100.5 + i for i in range(count)],
            "Volume": [1000 + i for i in range(count)],
            "classification": ["fake"] * count,
            "trend_state": [TREND_NEUTRAL] * count,
        },
        index=index,
    )


def test_missing_calendar_day_values_include_weekday_holidays_only() -> None:
    df = _make_daily_df(["2026-02-13", "2026-02-17"])
    missing = _missing_calendar_day_values(df)

    assert "2026-02-15" not in missing
    assert "2026-02-16" in missing


def test_build_figure_adds_missing_day_rangebreak_values() -> None:
    df = _make_daily_df(["2026-02-13", "2026-02-17"])
    fig = build_figure(
        df,
        gray_fake=False,
        interval="1d",
        hide_market_closed_gaps=True,
        display_timezone="America/Chicago",
        use_24h_time=False,
    )

    rangebreak_values: list[str] = []
    for rb in fig.layout.xaxis.rangebreaks:
        values = list(getattr(rb, "values", ()) or ())
        rangebreak_values.extend(str(v) for v in values)

    assert "2026-02-16" in rangebreak_values
    assert "2026-02-15" not in rangebreak_values


def test_build_figure_intraday_uses_category_axis_when_hiding_gaps() -> None:
    df = _make_intraday_df(["2026-02-13", "2026-02-17"])
    fig = build_figure(
        df,
        gray_fake=False,
        interval="15m",
        hide_market_closed_gaps=True,
        display_timezone="America/Chicago",
        use_24h_time=False,
    )

    assert fig.layout.xaxis.type == "category"
    assert len(fig.layout.xaxis.rangebreaks) == 0
    assert fig.layout.xaxis.tickmode == "array"
    assert list(fig.layout.xaxis.ticktext) == ["2/13", "2/17"]
    assert len(fig.layout.xaxis.tickvals) == 2
