from __future__ import annotations

import json
from pathlib import Path

from src.tools.hyperliquid_daily_report import (
    format_v76_anti_chase_impact,
    format_v76_lifecycle_report,
    format_v76_lifecycle_scorecard,
    format_market_confluence_line,
    summarize_v76_anti_chase_impact,
    summarize_v76_lifecycle,
    summarize_v76_lifecycle_scorecard,
)
from src.tools.v76_paper_runtime import STRICT_ID


def _append(path: Path, row: dict) -> None:
    path.parent.mkdir(parents=True, exist_ok=True)
    with path.open("a", encoding="utf-8") as fh:
        fh.write(json.dumps(row) + "\n")


def test_summarize_v76_lifecycle_counts_entries_exits_open_positions(tmp_path: Path) -> None:
    root = tmp_path / "experiments" / STRICT_ID
    _append(root / "trade_journal.jsonl", {
        "event": "entry",
        "coin": "BTC",
        "live_order_allowed": False,
        "mainnet_signed_action": False,
    })
    _append(root / "trade_journal.jsonl", {
        "event": "exit",
        "coin": "BTC",
        "exit_reason": "take_profit",
        "net_pnl_usd": "0.25",
        "mfe_pct": "1.50",
        "mae_pct": "-0.40",
        "live_order_allowed": False,
        "mainnet_signed_action": False,
    })
    _append(root / "trade_journal.jsonl", {
        "event": "exit",
        "coin": "ETH",
        "exit_reason": "stop_loss",
        "net_pnl_usd": "-0.10",
        "mfe_pct": "0.30",
        "mae_pct": "-1.20",
        "live_order_allowed": False,
        "mainnet_signed_action": False,
    })
    (root / "state.json").write_text(json.dumps({"open_positions": {"SOL": {"entry": "100"}}}))

    summary = summarize_v76_lifecycle(STRICT_ID, tmp_path)

    assert summary["entries"] == 1
    assert summary["exits"] == 2
    assert summary["legacy_synthetic_exits"] == 0
    assert summary["open_positions"] == 1
    assert summary["open_by_coin"] == {"SOL": 1}
    assert summary["exit_reasons"] == {"take_profit": 1, "stop_loss": 1}
    assert summary["closed_net_pnl_usd"] == "0.15"
    assert summary["pnl_by_coin"] == {"BTC": "0.25", "ETH": "-0.10"}
    assert summary["pnl_by_exit_reason"] == {"stop_loss": "-0.10", "take_profit": "0.25"}
    assert summary["winning_exits"] == 1
    assert summary["losing_exits"] == 1
    assert summary["gross_wins_usd"] == "0.25"
    assert summary["gross_losses_usd"] == "-0.10"
    assert summary["avg_mfe_pct"] == "0.90"
    assert summary["avg_mae_pct"] == "-0.80"
    assert summary["live_order_allowed_count"] == 0

    line = format_v76_lifecycle_report(summary)
    assert "v76 Lifecycle: entries=1, exits=2, open=1" in line
    assert "avg_mfe=0.90%" in line
    assert "live_flags=0" in line

    scorecard = summarize_v76_lifecycle_scorecard(summary)
    assert scorecard["evidence_source"] == "true_lifecycle_exits_only"
    assert scorecard["closed_trades"] == 2
    assert scorecard["winrate_pct"] == "50.00"
    assert scorecard["profit_factor"] == "2.50"
    assert scorecard["net_pnl_usd"] == "0.15"
    assert "lifecycle_sample_too_small" in scorecard["blockers"]
    scorecard_line = format_v76_lifecycle_scorecard(scorecard)
    assert "v76 Lifecycle Scorecard:" in scorecard_line
    assert "source=true_lifecycle_exits_only" in scorecard_line
    assert "live=nein" in scorecard_line


def test_summarize_v76_lifecycle_warns_on_live_flags(tmp_path: Path) -> None:
    root = tmp_path / "experiments" / STRICT_ID
    _append(root / "trade_journal.jsonl", {
        "event": "exit",
        "coin": "BTC",
        "exit_reason": "take_profit",
        "net_pnl_usd": "0.25",
        "live_order_allowed": True,
    })

    summary = summarize_v76_lifecycle(STRICT_ID, tmp_path)

    assert summary["live_order_allowed_count"] == 1


def test_summarize_v76_anti_chase_impact_counts_blocks_and_post_filter_exits(tmp_path: Path) -> None:
    root = tmp_path / "experiments" / STRICT_ID
    _append(root / "signal_journal.jsonl", {
        "timestamp": "2026-06-29T10:00:00+00:00",
        "coin": "BTC",
        "final_decision": "paper_opened_lifecycle",
        "block_reason": [],
    })
    _append(root / "signal_journal.jsonl", {
        "timestamp": "2026-06-29T11:00:00+00:00",
        "coin": "ETH",
        "final_decision": "blocked:anti_chase_overextended_no_retest",
        "block_reason": ["anti_chase_overextended_no_retest"],
    })
    _append(root / "signal_journal.jsonl", {
        "timestamp": "2026-06-29T11:05:00+00:00",
        "coin": "SOL",
        "final_decision": "blocked:anti_chase_no_retest_reclaim",
        "block_reason": ["anti_chase_no_retest_reclaim"],
    })
    _append(root / "trade_journal.jsonl", {
        "timestamp": "2026-06-29T10:30:00+00:00",
        "event": "exit",
        "coin": "BTC",
        "exit_reason": "take_profit",
        "net_pnl_usd": "0.50",
    })
    _append(root / "trade_journal.jsonl", {
        "timestamp": "2026-06-29T11:30:00+00:00",
        "event": "exit",
        "coin": "ETH",
        "exit_reason": "stop_loss",
        "net_pnl_usd": "-0.20",
    })
    _append(root / "trade_journal.jsonl", {
        "timestamp": "2026-06-29T11:45:00+00:00",
        "event": "exit",
        "coin": "SOL",
        "exit_reason": "trailing_stop",
        "net_pnl_usd": "0.40",
    })

    impact = summarize_v76_anti_chase_impact(STRICT_ID, tmp_path)

    assert impact["status"] == "collecting"
    assert impact["signals_seen"] == 3
    assert impact["paper_opened_lifecycle"] == 1
    assert impact["anti_chase_blocked_total"] == 2
    assert impact["anti_chase_blockers"] == {"anti_chase_overextended_no_retest": 1, "anti_chase_no_retest_reclaim": 1}
    assert impact["post_filter_exits"] == 2
    assert impact["post_filter_net_pnl_usd"] == "0.20"
    assert impact["post_filter_winrate_pct"] == "50.00"
    assert impact["post_filter_exit_reasons"] == {"stop_loss": 1, "trailing_stop": 1}
    line = format_v76_anti_chase_impact(impact)
    assert "v76 Anti-Chase Impact:" in line
    assert "blocked_total=2" in line
    assert "live=nein" in line


def test_format_market_confluence_line_renders_latest_snapshot():
    payload = {
        "confluence": {
            "market_regime": "risk_on",
            "eligible_count": 2,
            "scores": {
                "BTC": {"final_score": "82.50", "recommendation": "paper_candidate"},
                "ETH": {"final_score": "77.00", "recommendation": "paper_candidate"},
                "WLD": {"final_score": "42.00", "recommendation": "block_new_entry"},
            },
        }
    }

    line = format_market_confluence_line(payload)

    assert "Market Confluence Light:" in line
    assert "regime=risk_on" in line
    assert "eligible=2" in line
    assert "BTC" in line
    assert "live=nein" in line
