"""CLI `fxhnt bybit-ingest-long-short` — universe resolve + long_ratio ingest into bybit_features. NO network:
the BybitAccountRatio adapter is monkeypatched with a fake, and the operational DSN points at a temp sqlite db."""
from __future__ import annotations

from typer.testing import CliRunner

from fxhnt.cli import app


class _FakeRatio:
    def long_ratio_history(self, symbol, *, start_ms=None):
        return {19000: 0.55, 19001: 0.48}


class _FakeFunding:
    def active_universe(self):
        return ["BTCUSDT", "ETHUSDT"]


def _patch(monkeypatch, tmp_path):
    dsn = f"sqlite:///{tmp_path / 'op.db'}"
    monkeypatch.setenv("FXHNT_OPERATIONAL_DSN", dsn)
    from fxhnt import cli as climod
    climod.get_settings.cache_clear()
    monkeypatch.setattr("fxhnt.adapters.data.bybit_account_ratio.BybitAccountRatio",
                        lambda *a, **k: _FakeRatio())
    monkeypatch.setattr("fxhnt.adapters.data.bybit_funding.BybitFunding", lambda *a, **k: _FakeFunding())
    return dsn


def test_cli_all_active(monkeypatch, tmp_path):
    dsn = _patch(monkeypatch, tmp_path)
    res = CliRunner().invoke(app, ["bybit-ingest-long-short", "--symbols", "all"])
    assert res.exit_code == 0, res.output
    assert "2 symbols (all active USDT perps)" in res.output
    assert "done: 2 symbols, 4 day-rows" in res.output

    from fxhnt.adapters.warehouse.timescale_feature_store import TimescaleFeatureStore
    store = TimescaleFeatureStore(dsn, table="bybit_features")
    assert store.read_panel(["BTCUSDT", "ETHUSDT"], "long_ratio") == {
        "BTCUSDT": {19000: 0.55, 19001: 0.48},
        "ETHUSDT": {19000: 0.55, 19001: 0.48},
    }
    # ONLY long_ratio was written.
    assert store.crypto_funding_panel() == {}
    store.close()


def test_cli_explicit_symbols_and_from(monkeypatch, tmp_path):
    _patch(monkeypatch, tmp_path)
    res = CliRunner().invoke(app, ["bybit-ingest-long-short", "--symbols", "BTCUSDT", "--from", "2023-01"])
    assert res.exit_code == 0, res.output
    assert "1 symbols (explicit)" in res.output
    assert "floor=2023-01" in res.output


def test_cli_liquid_empty_universe_errors(monkeypatch, tmp_path):
    # No turnover data in a fresh store -> liquid_universe is empty -> the command errors clearly.
    _patch(monkeypatch, tmp_path)
    res = CliRunner().invoke(app, ["bybit-ingest-long-short", "--symbols", "liquid"])
    assert res.exit_code == 1
    assert "empty symbol universe" in res.output


def test_cli_bad_from_month(monkeypatch, tmp_path):
    _patch(monkeypatch, tmp_path)
    res = CliRunner().invoke(app, ["bybit-ingest-long-short", "--symbols", "BTCUSDT", "--from", "2023"])
    assert res.exit_code == 1
    assert "must be YYYY-MM" in res.output
