from __future__ import annotations

import json
from pathlib import Path

from dashboard import build_dashboard_snapshot


def _write_journal(path: Path, strategy_id: str, pnls: list[float], coins: list[str] | None = None) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    coins = coins or ["BTC", "ETH", "SOL", "HYPE"]
    lines: list[str] = []
    for i, pnl in enumerate(pnls):
        coin = coins[i % len(coins)]
        lines.append(json.dumps({
            "event_type": "entry",
            "coin": coin,
            "price": 100.0,
            "size": 1.0,
            "extra": {"strategy_id": strategy_id, "risk_usd": 2.5},
        }))
        lines.append(json.dumps({
            "event_type": "exit",
            "coin": coin,
            "realized_pnl_usd": pnl,
            "extra": {"strategy_id": strategy_id},
        }))
    path.write_text("\n".join(lines) + "\n", encoding="utf-8")


def test_scorecard_marks_diversified_profitable_sample_live_preview_ready(tmp_path: Path) -> None:
    runtime = tmp_path / "state"
    exp = runtime / "experiments" / "balanced_breakout"
    pnls = [0.8, 0.7, -0.2, 0.6, 0.5, -0.1] * 5
    _write_journal(exp / "Tradeanalyse" / "trade_journal.jsonl", "balanced_breakout", pnls)

    bot = build_dashboard_snapshot(runtime_dir=runtime).paper_bots[0]

    assert bot.scorecard.status == "Live-preview-ready"
    assert bot.scorecard.sample_size == 30
    assert bot.scorecard.profit_factor > 1.5
    assert bot.scorecard.coin_leakage_pct <= 50.0


def test_scorecard_blocks_negative_strategy_after_minimum_sample(tmp_path: Path) -> None:
    runtime = tmp_path / "state"
    exp = runtime / "experiments" / "bad_mean_reversion"
    _write_journal(exp / "Tradeanalyse" / "trade_journal.jsonl", "bad_mean_reversion", [-0.4, -0.2, 0.1, -0.3, -0.1])

    bot = build_dashboard_snapshot(runtime_dir=runtime).paper_bots[0]

    assert bot.scorecard.status == "Blocked"
    assert "total PnL not positive" in bot.scorecard.reasons


def test_scorecard_keeps_tiny_or_research_samples_in_research(tmp_path: Path) -> None:
    runtime = tmp_path / "state"
    exp = runtime / "experiments" / "candidate_v65_signal_sampler_aggressive"
    _write_journal(exp / "Tradeanalyse" / "trade_journal.jsonl", "candidate_v65_signal_sampler_aggressive", [1.0, 0.5, -0.1, 0.2, 0.3])

    bot = build_dashboard_snapshot(runtime_dir=runtime).paper_bots[0]

    assert bot.scorecard.status == "Research"
    assert "research sampler / not champion" in bot.scorecard.reasons
