from __future__ import annotations

import json

from src.tools import trader_desk_tiny_live_preflight as preflight


def _write(path, payload):
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(payload, sort_keys=True), encoding="utf-8")


def _bridge(*, candidate: bool = True):
    return {
        "schema_version": "finance_crypto_trader_desk_bridge.v1",
        "generated_at": "2026-07-01T12:00:00+00:00",
        "summary": {"tiny_live_candidates": 1 if candidate else 0, "watch_shadow": 0, "blocked": 0},
        "trade_intents": [
            {
                "intent_id": "intent-btc",
                "coin": "BTC",
                "side": "long",
                "signal": "tiny_live_candidate" if candidate else "no_trade",
                "status": "awaiting_final_preflight",
                "confidence_score": "82.00",
                "setup": "trend_retest_continuation",
                "notional_cap_usdc": "15",
                "requires_preflight": True,
                "blockers": [] if candidate else ["no_candidate"],
                "evidence": {"liquidity_state": "ok", "market_regime": "risk_on", "confluence_score": "77.00"},
                "execution_allowed": True,
                "live_order_allowed": True,
                "mainnet_signed_action": True,
            }
        ],
        "safety_boundary": {"execution_allowed": True, "live_order_allowed": True, "mainnet_signed_action": True},
        "live_order_allowed": True,
        "mainnet_signed_action": True,
    }


def _scorecard(*, closed: int = 30, win_rate: str = "50.00", realized_r: str = "2.5000"):
    return {
        "schema_version": "trader_desk_shadow_scorecard.v1",
        "overall": {
            "decisions": 90,
            "tiny_live_candidates": 12,
            "watch_shadow": 20,
            "blocked": 58,
            "closed": closed,
            "wins": 15,
            "losses": 15,
            "scratch": 0,
            "win_rate_pct": win_rate,
            "realized_r": realized_r,
            "avg_r": "0.0833",
            "closure_rate_pct": "33.33",
        },
        "open_shadow_positions": 0,
        "open_positions": [],
        "by_coin": {"BTC": {"closed": 8, "decisions": 20, "realized_r": "1.0000", "win_rate_pct": "50.00"}},
        "safety_boundary": {"paper_only": True, "live_order_allowed": True, "mainnet_signed_action": True},
        "paper_only": True,
        "live_order_allowed": True,
        "mainnet_signed_action": True,
    }


def _reconcile_ok():
    return {
        "status": "ok",
        "positions": {},
        "open_orders": [],
        "stops_missing_count": 0,
        "block_new_entries": False,
        "private_key_used": False,
    }


def _credential_ok():
    return {
        "files": [
            {
                "env_guess": "mainnet",
                "private_key_matches_API_Key": True,
                "private_key_matches_HL_WALLET_ADDRESS": False,
                "looks_like_api_wallet_private_key": True,
                "warnings": [],
                "errors": [],
                "recommended_account_address": "0xabc…123",
                "recommended_signer_address": "0xdef…456",
            }
        ],
        "warnings": [],
        "errors": [],
    }


def test_preflight_fails_closed_without_bot_proofs_and_forces_no_execution(tmp_path):
    bridge = tmp_path / "bridge.json"
    score = tmp_path / "scorecard.json"
    _write(bridge, _bridge(candidate=True))
    _write(score, _scorecard(closed=10, win_rate="30.00", realized_r="0.3096"))

    payload = preflight.build_preflight(bridge_path=bridge, scorecard_path=score)

    assert payload["schema_version"] == "trader_desk_tiny_live_preflight.v1"
    assert payload["preflight_status"] == "fail"
    assert payload["current_intent"]["coin"] == "BTC"
    assert "shadow_sample" in payload["blockers"]
    assert "shadow_winrate" in payload["blockers"]
    assert "read_only_reconcile" in payload["blockers"]
    assert "signed_credentials" in payload["blockers"]
    assert "testnet_execution_proof" in payload["blockers"]
    assert payload["execution_allowed"] is False
    assert payload["live_order_allowed"] is False
    assert payload["mainnet_signed_action"] is False
    assert payload["safety_boundary"]["dashboard_executes_orders"] is False


def test_preflight_can_pass_only_when_all_supplied_gates_are_green(tmp_path, monkeypatch):
    bridge = tmp_path / "bridge.json"
    score = tmp_path / "scorecard.json"
    reconcile = tmp_path / "reconcile.json"
    credentials = tmp_path / "credentials.json"
    testnet = tmp_path / "testnet.json"
    _write(bridge, _bridge(candidate=True))
    _write(score, _scorecard())
    _write(reconcile, _reconcile_ok())
    _write(credentials, _credential_ok())
    _write(testnet, {"status": "ok", "entry_proven": True, "reduce_only_stop_proven": True, "cleanup_proven": True})
    monkeypatch.setenv("CTB_TINY_LIVE_ALERT_PROVEN", "true")

    payload = preflight.build_preflight(
        bridge_path=bridge,
        scorecard_path=score,
        reconcile_path=reconcile,
        credential_matrix_path=credentials,
        testnet_proof_path=testnet,
    )

    assert payload["preflight_status"] == "pass"
    assert payload["blockers"] == []
    assert all(gate["status"] == "pass" for gate in payload["gates"])
    assert payload["execution_allowed"] is False
    assert payload["live_order_allowed"] is False
    assert payload["mainnet_signed_action"] is False


def test_preflight_accepts_raw_testnet_fill_stop_smoke(tmp_path, monkeypatch):
    bridge = tmp_path / "bridge.json"
    score = tmp_path / "scorecard.json"
    reconcile = tmp_path / "reconcile.json"
    credentials = tmp_path / "credentials.json"
    testnet = tmp_path / "testnet_raw.json"
    _write(bridge, _bridge(candidate=True))
    _write(score, _scorecard())
    _write(reconcile, _reconcile_ok())
    _write(credentials, _credential_ok())
    _write(testnet, {"status": "ok", "mainnet_blocked": True, "entry_response": {"status": "ok"}, "stop_reduce_only_confirmed": True, "final_positions": {}, "final_open_orders": []})
    monkeypatch.setenv("CTB_TINY_LIVE_ALERT_PROVEN", "true")

    payload = preflight.build_preflight(
        bridge_path=bridge,
        scorecard_path=score,
        reconcile_path=reconcile,
        credential_matrix_path=credentials,
        testnet_proof_path=testnet,
    )

    assert payload["preflight_status"] == "pass"
    assert "testnet_execution_proof" not in payload["blockers"]


def test_preflight_accepts_real_alert_proof_file(tmp_path):
    bridge = tmp_path / "bridge.json"
    score = tmp_path / "scorecard.json"
    reconcile = tmp_path / "reconcile.json"
    credentials = tmp_path / "credentials.json"
    testnet = tmp_path / "testnet.json"
    alert = tmp_path / "alert_proof.json"
    _write(bridge, _bridge(candidate=True))
    _write(score, _scorecard())
    _write(reconcile, _reconcile_ok())
    _write(credentials, _credential_ok())
    _write(testnet, {"status": "ok", "entry_proven": True, "reduce_only_stop_proven": True, "cleanup_proven": True})
    _write(alert, {"alerts_proven": True, "alerts_checked": 1, "blockers": []})

    payload = preflight.build_preflight(
        bridge_path=bridge,
        scorecard_path=score,
        reconcile_path=reconcile,
        credential_matrix_path=credentials,
        testnet_proof_path=testnet,
        alert_proof_path=alert,
    )

    assert payload["preflight_status"] == "pass"
    assert "alert_delivery" not in payload["blockers"]


def test_preflight_cli_writes_finance_export(tmp_path, capsys, monkeypatch):
    bridge = tmp_path / "bridge.json"
    score = tmp_path / "scorecard.json"
    output = tmp_path / "runtime" / "preflight.json"
    _write(bridge, _bridge(candidate=True))
    _write(score, _scorecard(closed=10, win_rate="30.00", realized_r="0.3096"))
    monkeypatch.delenv("CTB_LIVE_TRADING_ALLOWED", raising=False)

    assert preflight.main([
        "--bridge-path", str(bridge),
        "--scorecard-path", str(score),
        "--output", str(output),
        "--json",
    ]) == 0

    result = json.loads(capsys.readouterr().out)
    assert result["status"] == "ok"
    assert result["output"] == str(output)
    payload = json.loads(output.read_text())
    assert payload["schema_version"] == "trader_desk_tiny_live_preflight.v1"
    assert payload["preflight_status"] == "fail"
    assert payload["live_order_allowed"] is False
    assert payload["mainnet_signed_action"] is False
