"""Tests for atm.report."""
from __future__ import annotations

import pytest

from atm.journal import TradeEntry
from atm.report import iso_week, weekly_report

WEEK = "2026-16"
BASE_TS = "2026-04-14T10:00:00"


def _trade(
    outcome: str,
    direction: str = "BUY",
    entry: float = 100.0,
    sl: float = 90.0,
    exit_: float | None = None,
    detected_ts: str | None = None,
    ts: str = BASE_TS,
) -> TradeEntry:
    return TradeEntry(
        ts=ts,
        direction=direction,
        symbol="US30",
        entry=entry,
        sl=sl,
        tp1=None,
        tp2=None,
        exit=exit_,
        outcome=outcome,
        detected_ts=detected_ts,
        notes="",
    )


def test_win_rate_and_pnl() -> None:
    """5 synthetic trades: tp1 +2R, tp2 +3R, sl -1.5R, manual +2R, open excluded."""
    trades = [
        # tp1: BUY, entry=100, sl=90, exit=120 → R = (120-100)/(100-90) = +2.0
        _trade("tp1", exit_=120.0, detected_ts="2026-04-14T09:59:55"),
        # tp2: BUY, entry=100, sl=90, exit=130 → R = (130-100)/(100-90) = +3.0
        _trade("tp2", exit_=130.0),
        # sl:  BUY, entry=100, sl=90, exit=85  → R = (85-100)/(100-90) = -1.5
        _trade("sl", exit_=85.0, detected_ts="2026-04-14T09:59:50"),
        # manual: SELL, entry=100, sl=110, exit=80 → R = (80-100)/(100-110) = +2.0
        _trade("manual", direction="SELL", sl=110.0, exit_=80.0),
        # open: excluded from counts
        _trade("open"),
    ]

    report = weekly_report(trades, WEEK)

    assert report.week == WEEK
    assert report.n_trades == 4
    assert report.n_wins == 2
    assert report.n_losses == 2
    assert report.win_rate == pytest.approx(0.5)
    assert report.pnl_r == pytest.approx(5.5)
    # slippage: trade[0]=5s, trade[2]=10s → avg=7.5s
    assert report.avg_slippage == pytest.approx(7.5)


def test_iso_week() -> None:
    assert iso_week("2026-04-14T10:00:00") == "2026-16"
    assert iso_week("2026-01-01T00:00:00") == "2026-01"


def test_empty_week() -> None:
    report = weekly_report([], WEEK)
    assert report.n_trades == 0
    assert report.n_wins == 0
    assert report.n_losses == 0
    assert report.win_rate == 0.0
    assert report.pnl_r == 0.0
    assert report.avg_slippage is None
