"""Unit tests for the paper-book equity curve math (pure function)."""

from datetime import date, datetime
from types import SimpleNamespace

from app.services.paper_trade_service import build_equity_curve


def _trade(**kw):
    defaults = dict(
        ticker_id=1,
        direction="long",
        entry_price=100.0,
        shares=10.0,
        status="open",
        opened_at=datetime(2026, 1, 5, 15, 0),
        closed_at=None,
        close_price=None,
    )
    defaults.update(kw)
    return SimpleNamespace(**defaults)


BENCH = {
    date(2026, 1, 5): 500.0,
    date(2026, 1, 6): 505.0,
    date(2026, 1, 7): 510.0,
}


def test_open_long_marks_to_market_vs_benchmark():
    trades = [_trade()]
    ticker_closes = {1: {date(2026, 1, 5): 100.0, date(2026, 1, 6): 104.0, date(2026, 1, 7): 106.0}}
    curve = build_equity_curve(trades, ticker_closes, BENCH)

    assert [p["date"] for p in curve] == ["2026-01-05", "2026-01-06", "2026-01-07"]
    # Day 3: book +6 * 10 shares; benchmark: 1000 basis * (510-500)/500 = +20
    assert curve[-1]["book_pnl"] == 60.0
    assert curve[-1]["benchmark_pnl"] == 20.0


def test_closed_trade_freezes_both_legs_at_close_date():
    trades = [
        _trade(
            status="closed",
            closed_at=datetime(2026, 1, 6, 21, 0),
            close_price=104.0,
        )
    ]
    # Ticker keeps rising after the close — must NOT affect the curve.
    ticker_closes = {1: {date(2026, 1, 5): 100.0, date(2026, 1, 6): 104.0, date(2026, 1, 7): 999.0}}
    curve = build_equity_curve(trades, ticker_closes, BENCH)

    # Realized +4 * 10 from close date onward.
    assert curve[-1]["book_pnl"] == 40.0
    # Benchmark leg also freezes at the close date: (505-500)/500 * 1000 = +10.
    assert curve[-1]["benchmark_pnl"] == 10.0


def test_short_direction_and_missing_ticker_prices():
    trades = [
        _trade(direction="short"),
        _trade(ticker_id=2),  # no price history — contributes nothing
    ]
    ticker_closes = {1: {date(2026, 1, 5): 100.0, date(2026, 1, 6): 96.0, date(2026, 1, 7): 90.0}}
    curve = build_equity_curve(trades, ticker_closes, BENCH)

    # Short: entry 100 → 90 = +10/share * 10 shares.
    assert curve[-1]["book_pnl"] == 100.0
    # Benchmark counterfactual is long-SPY for the priced trade only.
    assert curve[-1]["benchmark_pnl"] == 20.0


def test_empty_without_trades_or_benchmark():
    assert build_equity_curve([], {}, BENCH) == []
    assert build_equity_curve([_trade()], {}, {}) == []
