import datetime as dt

from fxhnt.adapters.persistence.forward_nav import ForwardNavRepo
from fxhnt.application.bybit_exec_record import (
    compute_crypto_exec_return,
    crypto_envelope,
    record_bybit_exec_track,
)


class _Repo:
    def __init__(self, alloc):
        self._alloc = alloc

    def current_allocation(self):
        return self._alloc


def test_envelope_flattens_when_bybit_4edge_defunded():
    # de-funded/absent bybit_4edge -> envelope 0 -> the book flattens (plan_orders would size everything to 0).
    assert crypto_envelope(_Repo({}), 50_000.0) == 0.0
    assert crypto_envelope(_Repo({"bybit_4edge": 0.0}), 50_000.0) == 0.0


def test_end_to_end_envelope_basis_exec_return_recorded(tmp_path):
    # Simulate the reconcile->record data flow with a real repo (no Dagster/broker): inception, then a day
    # with +$100 price pnl + $50 funding - $20 fees on a $10k envelope behind a large (irrelevant) equity.
    repo = ForwardNavRepo(f"sqlite:///{tmp_path/'c.db'}")
    repo.migrate()
    at0 = dt.datetime(2026, 7, 10)
    # inception run: no prior book -> None return, carry basis (100 units @ 100, envelope 10k).
    prior = repo.get_book_state("bybit_4edge_exec_pos")
    assert compute_crypto_exec_return(prior, {"BTCUSDT": 100.0}, 0.0, 0.0) is None
    record_bybit_exec_track(repo, None, {"BTCUSDT": 100.0}, {"BTCUSDT": 100.0}, 10_000.0,
                            1_700_000_000_000, "2026-07-10", at0)
    # next run: marks 100->101 (+$100), funding +$50, fees $20 -> (100+50-20)/10000 = +1.30%.
    prior = repo.get_book_state("bybit_4edge_exec_pos")
    r = compute_crypto_exec_return(prior, {"BTCUSDT": 101.0}, 50.0, 20.0)
    assert abs(r - 0.013) < 1e-9
    record_bybit_exec_track(repo, r, {"BTCUSDT": 100.0}, {"BTCUSDT": 101.0}, 10_000.0,
                            1_700_100_000_000, "2026-07-11", dt.datetime(2026, 7, 11))
    assert any(abs(row.ret - 0.013) < 1e-9 for row in repo.nav_history("bybit_4edge_exec"))
