import datetime as dt

from fxhnt.adapters.persistence.paper_repo import PaperRepo
from fxhnt.domain.paper import Position, Trade


def test_paper_repo_roundtrip():
    repo = PaperRepo("sqlite://")
    repo.migrate()
    at = dt.datetime(2026, 6, 21, 23, 30, tzinfo=dt.UTC)
    repo.replace_positions(
        "2026-06-21",
        [Position("stablecoin_rotation", "USDTUSD", -25000.0, 2.0, "2026-06-21")],
        weight_by_sleeve={"stablecoin_rotation": 0.5}, at=at)
    repo.record_trades(
        [Trade("2026-06-21T23:30:00Z", "stablecoin_rotation", "USDTUSD", "SELL", 25000.0, 2.0, "rebalance")],
        at=at)
    pos = repo.latest_positions()
    assert pos[0].symbol == "USDTUSD" and pos[0].qty == -25000.0
    assert repo.weight_for("stablecoin_rotation") == 0.5
    assert repo.recent_trades(10)[0].side == "SELL"


def test_replace_trades_idempotent_per_run_date():
    repo = PaperRepo("sqlite://")
    repo.migrate()
    at = dt.datetime(2026, 6, 21, 23, 30, tzinfo=dt.UTC)
    rd = "2026-06-21"
    trades = [Trade("2026-06-21T23:30:00Z", "s", "BTC", "BUY", 1.0, 100.0, "rebalance")]
    repo.replace_trades(rd, trades, at=at)
    repo.replace_trades(rd, trades, at=at)            # re-run same run_date
    assert len(repo.recent_trades(50)) == 1           # replaced, not appended

    # a different run_date appends alongside
    repo.replace_trades("2026-06-22", [Trade("2026-06-22T23:30:00Z", "s", "ETH", "BUY", 2.0, 50.0, "rebalance")], at=at)
    recent = repo.recent_trades(50)
    assert len(recent) == 2
    assert recent[0].symbol == "ETH"                  # newest-first


def test_realized_pnl_roundtrip():
    repo = PaperRepo("sqlite://")
    repo.migrate()
    assert repo.realized_pnl() == 0.0
    repo.add_realized(150.0)
    repo.add_realized(50.0)
    assert repo.realized_pnl() == 200.0


def test_realized_pnl_through_filters_by_run_date():
    repo = PaperRepo("sqlite://")
    repo.migrate()
    repo.set_realized_for_run_date("2026-06-19", 5.0)
    repo.set_realized_for_run_date("2026-06-21", 10.0)
    # 2026-06-20 sees only the 06-19 booking (06-21 is in the future relative to it).
    assert repo.realized_pnl_through("2026-06-20") == 5.0
    # 2026-06-21 sees both.
    assert repo.realized_pnl_through("2026-06-21") == 15.0
    # All-time stays the sum of every dated key.
    assert repo.realized_pnl() == 15.0
