from __future__ import annotations

from decimal import Decimal

from src.trader_desk.decision import DeskMandate, build_trade_plan, build_trader_desk_report, format_trader_desk_report


def _coin(mid="100", trend="bullish", blockers=None, score="82.00", spread="0.03", atr="1.20"):
    blockers = blockers or []
    return {
        "price": {"mid": mid},
        "trend": {"state": trend},
        "momentum": {"state": "constructive"},
        "volatility": {"state": "tradeable", "atr_pct": atr},
        "liquidity": {"state": "ok", "spread_pct": spread},
        "derivatives": {"funding": "0.000001", "crowding_state": "neutral"},
        "risk": {"blockers": blockers},
        "sentiment": {
            "source": "tradingview_community_research_context",
            "research_only": True,
            "recent_ideas_count": 3,
            "track_record": {"evaluated": 12, "hitrate_pct": "60.00"},
        },
        "fundamentals": {"source": "coingecko_markets", "status": "loaded"},
    }


def _payload():
    return {
        "live_order_allowed": False,
        "mainnet_signed_action": False,
        "market_snapshot": {
            "market_regime": "risk_on",
            "coins": {
                "BTC": _coin(),
                "ETH": _coin(score="55.00", blockers=["spread_too_wide"], spread="0.20"),
            },
        },
        "confluence": {
            "market_regime": "risk_on",
            "scores": {
                "BTC": {"final_trade_score": "82.00", "blockers": [], "recommendation": "paper_candidate"},
                "ETH": {"final_trade_score": "55.00", "blockers": ["spread_too_wide", "confluence_below_threshold"], "recommendation": "block_new_entry"},
            },
        },
    }


def test_trader_desk_promotes_high_quality_long_to_tiny_candidate_without_live_side_effects():
    plan = build_trade_plan(_payload(), "BTC", DeskMandate())

    assert plan.action == "tiny_live_candidate"
    assert plan.direction == "long"
    assert plan.score == Decimal("87.00")
    assert plan.live_order_allowed is False
    assert plan.mainnet_signed_action is False
    assert plan.requires_preflight is True
    assert plan.stop_loss is not None
    assert plan.entry_zone["style"] == "retest_limit_zone"
    assert "community_track_record_supportive_research_only" in plan.reasons


def test_trader_desk_blocks_hard_market_quality_blockers():
    plan = build_trade_plan(_payload(), "ETH", DeskMandate())

    assert plan.action == "no_trade"
    assert "spread_too_wide" in plan.blockers
    assert "confluence_below_threshold" in plan.blockers
    assert plan.notional_cap_usdc == "0"


def test_trader_desk_short_is_shadow_only_under_tiny_live_mandate():
    payload = _payload()
    payload["confluence"]["market_regime"] = "risk_off"
    payload["market_snapshot"]["market_regime"] = "risk_off"
    payload["market_snapshot"]["coins"]["BTC"]["trend"]["state"] = "bearish"
    payload["confluence"]["scores"]["BTC"]["final_trade_score"] = "85.00"

    plan = build_trade_plan(payload, "BTC", DeskMandate(long_only_tiny_live=True))

    assert plan.direction == "short"
    assert plan.action == "watch_shadow"
    assert "short_is_shadow_only_under_tiny_live_mandate" in plan.reasons


def test_trader_desk_report_is_sorted_and_read_only():
    report = build_trader_desk_report(_payload())

    assert report.schema_version == "trader_desk.v1"
    assert report.live_order_allowed is False
    assert report.mainnet_signed_action is False
    assert report.summary["tiny_live_candidates"] == 1
    assert report.summary["short_share_pct"] == "0.00"
    assert report.plans[0].coin == "BTC"
    text = format_trader_desk_report(report)
    assert "JARVIS Trader Desk v1" in text
    assert "live=nein" in text
