"""H3: `multistrat._build` drops `dates[-1]` when it equals UTC-today to shed an INCOMPLETE intraday bar.
Correct for the exec path (14:35 UTC, market OPEN), but WRONG for the nightly forward asset (23:30 UTC, after
the US close froze today's FINAL close) — it left `multistrat` forever one trading day stale. The behavior is
now controlled by a `drop_incomplete_today` flag (default True; the nightly `multistrat_nav` passes False)."""
from __future__ import annotations

import datetime

import numpy as np


def _closes_ending_today(instruments, n=300):
    """A price panel of `n` consecutive daily dates whose LAST date is exactly UTC-today."""
    today = datetime.datetime.now(datetime.timezone.utc).date()
    dates = [(today - datetime.timedelta(days=n - 1 - i)).isoformat() for i in range(n)]
    rng = np.random.default_rng(0)
    closes = {}
    for k, s in enumerate(instruments):
        steps = rng.normal(0.0003 * (1 if k % 2 else -1), 0.01, len(dates))
        px = 100.0 * np.cumprod(1 + steps)
        closes[s] = {d: float(px[i]) for i, d in enumerate(dates)}
    return dates, today.isoformat(), closes


def test_build_drops_today_by_default_keeps_with_flag_false():
    from fxhnt.domain.strategies.multistrat import INSTRUMENTS, _build
    _, today, closes = _closes_ending_today(INSTRUMENTS)

    dates_default, _ = _build(closes)                                    # exec basis (14:35 UTC, open)
    assert dates_default[-1] != today                                    # incomplete intraday bar dropped

    dates_keep, _ = _build(closes, drop_incomplete_today=False)          # nightly basis (23:30 UTC, closed)
    assert dates_keep[-1] == today                                       # today's FINAL close kept
    assert len(dates_keep) == len(dates_default) + 1


def test_multistrat_strategy_advance_books_today_when_flag_false():
    from fxhnt.application.paper_strategies import MultiStratStrategy
    from fxhnt.domain.strategies.multistrat import FUND_INSTRUMENTS
    _, today, closes = _closes_ending_today(FUND_INSTRUMENTS)

    class _Bars:
        def adj_closes(self, sym):   # noqa: ANN001, ANN202
            return closes[sym]

    keep_rows, _ = MultiStratStrategy(_Bars(), instruments=FUND_INSTRUMENTS,
                                      drop_incomplete_today=False).advance(None, {})
    assert keep_rows and keep_rows[-1][0] == today                       # today's booked return included

    drop_rows, _ = MultiStratStrategy(_Bars(), instruments=FUND_INSTRUMENTS).advance(None, {})   # default True
    assert drop_rows[-1][0] != today                                     # default still drops today


def test_target_weights_exec_path_still_drops_today():
    """The exec path (`execute-multistrat`, market OPEN) keeps the default True, so target_weights over a panel
    ending today gives the SAME vector as if today's (incomplete) bar were absent — no accidental use of the
    live intraday print."""
    from fxhnt.domain.strategies.multistrat import FUND_INSTRUMENTS, target_weights
    dates, today, closes = _closes_ending_today(FUND_INSTRUMENTS)

    w_with_today = target_weights(closes, FUND_INSTRUMENTS)              # default drops today
    closes_wo = {s: {d: v for d, v in closes[s].items() if d != today} for s in FUND_INSTRUMENTS}
    w_without_today = target_weights(closes_wo, FUND_INSTRUMENTS)
    assert set(w_with_today) == set(FUND_INSTRUMENTS)
    for s in FUND_INSTRUMENTS:
        assert abs(w_with_today[s] - w_without_today[s]) < 1e-12         # today's incomplete bar unused
