"""Carry accounting charges the intraday `worst_basis` (capped at −100%) INSTEAD of the daily-close basis
when one is available for (symbol, day); falls back to the daily-close basis when absent. Absent worst_basis
must be bit-identical to the current daily-close behavior."""
from fxhnt.application.paper_book import (
    carry_pnl,
    carry_return_by_symbol,
    sleeve_daily_carry,
)
from fxhnt.domain.paper import Position


def _pos(sym, qty, entry):
    return Position("xsfunding", sym, qty, entry, "2026-01-01")


def test_worst_basis_overrides_close_basis_when_present():
    funding = {"A": 0.01}
    close_basis = {"A": -0.007}            # benign daily-close basis (the LUNA 2022-05-12 −0.7%)
    worst = {"A": -1.63}                    # catastrophic intraday excursion (−163%)
    cr = carry_return_by_symbol(funding, close_basis, worst_basis_by_symbol=worst)
    # basis term replaced by max(-1.63, -1.0) = -1.0 (capped at total loss of the leg).
    assert abs(cr["A"] - (0.01 + (-1.0))) < 1e-12


def test_cap_at_minus_one_total_loss():
    cr = carry_return_by_symbol({"A": 0.0}, {"A": 0.0}, worst_basis_by_symbol={"A": -5.0})
    assert cr["A"] == -1.0                  # capped, never worse than −100%


def test_mild_worst_basis_not_capped():
    cr = carry_return_by_symbol({"A": 0.0}, {"A": -0.01}, worst_basis_by_symbol={"A": -0.30})
    assert abs(cr["A"] - (-0.30)) < 1e-12   # uses worst_basis (−30%), not the −1% close basis


def test_absent_worst_basis_falls_back_to_close_basis_bit_identical():
    funding = {"A": 0.02, "B": -0.01}
    basis = {"A": -0.05, "B": 0.02}
    baseline = carry_return_by_symbol(funding, basis)                       # no worst_basis arg
    with_none = carry_return_by_symbol(funding, basis, worst_basis_by_symbol=None)
    empty = carry_return_by_symbol(funding, basis, worst_basis_by_symbol={})
    assert with_none == baseline == empty   # absent → exactly the daily-close behavior


def test_partial_worst_basis_only_overrides_named_symbols():
    funding = {"A": 0.0, "B": 0.0}
    basis = {"A": -0.02, "B": -0.03}
    worst = {"A": -0.50}                     # only A has an intraday worst_basis
    cr = carry_return_by_symbol(funding, basis, worst_basis_by_symbol=worst)
    assert abs(cr["A"] - (-0.50)) < 1e-12    # A overridden
    assert abs(cr["B"] - (-0.03)) < 1e-12    # B still uses its close basis


def test_worst_basis_symbol_with_no_close_basis_still_charged():
    # A symbol present ONLY in worst_basis (no funding, no close basis) is charged the capped worst_basis.
    cr = carry_return_by_symbol({}, {}, worst_basis_by_symbol={"A": -0.40})
    assert abs(cr["A"] - (-0.40)) < 1e-12


def test_sleeve_return_and_pnl_reflect_the_charge():
    prev = [_pos("A", 0.1, 10.0)]            # long A, w=+1, gross=1
    funding = {"A": 0.01}
    close_basis = {"A": -0.007}
    benign = sleeve_daily_carry(prev, carry_return_by_symbol(funding, close_basis))
    charged = sleeve_daily_carry(
        prev, carry_return_by_symbol(funding, close_basis, worst_basis_by_symbol={"A": -1.63}))
    assert charged < benign                  # the intraday-liquidation charge reduces the carry return
    # equity contribution consistency still holds with the charge
    cr = carry_return_by_symbol(funding, close_basis, worst_basis_by_symbol={"A": -1.63})
    gross = sum(abs(p.qty * p.entry_price) for p in prev)
    assert abs(carry_pnl(prev, cr) / gross - sleeve_daily_carry(prev, cr)) < 1e-12
