from __future__ import annotations

from datetime import datetime, timezone

from fastapi.testclient import TestClient

from uforia.analytics.composite_family import (
    build_composite_component_series,
    build_composite_signal_series,
    build_composite_transition_series,
    build_market_composite_component_series,
    build_market_composite_signal_series,
    build_market_composite_transition_series,
)
from uforia.api.app import create_app
from uforia.api.settings import ApiSettings
from uforia.storage import DatasetName, DatasetStore

from .support import seed_options_context


def test_api_exposes_composite_family(tmp_path) -> None:
    store = DatasetStore(tmp_path)
    seed_options_context(store)
    start = datetime(2026, 3, 2, 0, tzinfo=timezone.utc)
    end = datetime(2026, 3, 3, 23, tzinfo=timezone.utc)

    for asset in ("BTC", "ETH"):
        signals = build_composite_signal_series(store, start, end, asset=asset)
        store.write(DatasetName.COMPOSITE_SIGNAL_SERIES, signals)
        components = build_composite_component_series(store, start, end, asset=asset)
        transitions = build_composite_transition_series(store, start, end, asset=asset)
        store.write(DatasetName.COMPOSITE_COMPONENT_SERIES, components)
        store.write(DatasetName.COMPOSITE_TRANSITION_SERIES, transitions)

    market_signals = build_market_composite_signal_series(store, start, end)
    store.write(DatasetName.COMPOSITE_SIGNAL_SERIES, market_signals)
    store.write(
        DatasetName.COMPOSITE_COMPONENT_SERIES,
        build_market_composite_component_series(store, start, end),
    )
    store.write(
        DatasetName.COMPOSITE_TRANSITION_SERIES,
        build_market_composite_transition_series(store, start, end),
    )

    client = TestClient(create_app(settings=ApiSettings(data_root=tmp_path), store=store))

    signals = client.get("/api/v1/composite/signals")
    btc_latest = client.get("/api/v1/composite/signals/btc_composite/latest")
    market_series = client.get("/api/v1/composite/signals/market_composite/series")
    btc_decomposition = client.get("/api/v1/composite/decomposition/btc_composite")
    btc_transitions = client.get("/api/v1/composite/transitions/btc_composite")

    assert signals.status_code == 200
    assert {"btc_composite", "eth_composite", "market_composite"} <= {
        item["id"] for item in signals.json()["data"]
    }

    assert btc_latest.status_code == 200
    latest_values = btc_latest.json()["data"]["latest_values"]
    assert {"sentiment_index", "directional_tilt", "fragility_index", "confidence_score"} <= set(
        latest_values
    )

    assert market_series.status_code == 200
    assert len(market_series.json()["data"]["points"]) > 0

    assert btc_decomposition.status_code == 200
    decomposition = btc_decomposition.json()["data"]
    assert len(decomposition["records"]) > 0
    assert len(decomposition["latest_contributors"]) > 0

    assert btc_transitions.status_code == 200
    transition_records = btc_transitions.json()["data"]["records"]
    assert len(transition_records) > 0
    assert {"sentiment", "directional", "fragility"} <= {
        item["index_type"] for item in transition_records
    }
