#!/usr/bin/env python3
"""Scenario D — see what the rule layer cuts, before you spend a token on the LLM.

LLM-Auto-Trader's real asset is not the prompt, it is `src/risk/` — a
deterministic layer that sits between the model's proposal and the order.
It is importable on its own, so you can feed it the worst proposals you can
imagine and read the verdicts, with no API key and no cost.

    LAT_HOME=/path/to/LLM-Auto-Trader python scenario_d_riskgate.py
"""
import os
import sys

sys.path.insert(0, os.environ["LAT_HOME"])

from config.settings import RiskSettings, AFMLSettings          # noqa: E402
from src.llm.response_parser import ActionType, TradeAction     # noqa: E402
from src.risk.circuit_breakers import CircuitBreakers           # noqa: E402
from src.risk.position_sizer import PositionSizer               # noqa: E402
from src.risk.risk_manager import RiskManager                   # noqa: E402

R = RiskSettings()
SYM = "BTC/USDT:USDT"
PX = 85000.0
EQUITY = 10000.0

breakers = CircuitBreakers(
    max_drawdown_pct=R.max_drawdown_pct,
    drawdown_warning_pct=R.drawdown_warning_pct,
    daily_loss_limit_pct=R.daily_loss_limit_pct,
)
rm = RiskManager(
    max_leverage=R.max_leverage, max_position_pct=R.max_position_pct,
    max_total_exposure_pct=R.max_total_exposure_pct,
    max_risk_per_trade_pct=R.max_risk_per_trade_pct,
    min_reward_risk_ratio=R.min_reward_risk_ratio,
    max_concurrent_positions=R.max_concurrent_positions,
    position_sizer=PositionSizer(taker_fee=0.001),
    circuit_breakers=breakers, afml_settings=AFMLSettings(),
)
rm.allowed_symbols = [SYM]


def act(**kw) -> TradeAction:
    base = dict(action=ActionType.OPEN_LONG, symbol=SYM, size_pct=10, leverage=2,
                order_type="market", stop_loss=PX * 0.98, take_profit=PX * 1.06,
                reasoning="scenario D probe")
    base.update(kw)
    return TradeAction(**base)


HELD = [{"symbol": f"X{i}/USDT:USDT", "notional": 500, "side": "long",
         "entry_price": 1, "size": 1} for i in range(3)]

CASES = [
    ("정상 진입 (10% · 2배 · RR 3:1)", {}, []),
    ("한도 초과 크기 (40%)", dict(size_pct=40), []),
    ("한도 초과 배율 (10배)", dict(leverage=10), []),
    ("손절이 없다", dict(stop_loss=None), []),
    ("보상/위험 0.5:1 (손절 -2%, 익절 +1%)", dict(take_profit=PX * 1.01), []),
    ("손절이 진입가 위 (롱인데)", dict(stop_loss=PX * 1.02), []),
    ("이미 3종목 보유 — 4번째", {}, HELD),
    ("총 노출 60% 초과 (5,500 보유 + 2,500 신규)", dict(size_pct=25),
     [{"symbol": "E/USDT:USDT", "notional": 5500, "side": "long",
       "entry_price": 1, "size": 1}]),
    ("허용 목록 밖 종목", dict(symbol="DOGE/USDT:USDT"), []),
]


def main() -> None:
    print(f"{'제안':<42} {'판정':<10} 사유 / 조정")
    print("-" * 100)
    for label, kw, positions in CASES:
        try:                       # gate 1: the response schema
            action = act(**kw)
        except Exception as e:
            reason = [ln for ln in str(e).splitlines() if "Value error" in ln
                      or "Input should" in ln]
            print(f"{label:<42} {'스키마거절':<10} "
                  f"{(reason[0].strip() if reason else str(e))[:70]}")
            continue
        v = rm.validate_action(action=action, equity=EQUITY,  # gate 2: the rules
                               open_positions=positions,
                               current_prices={action.symbol: PX},
                               confidence=0.7)
        verdict = "승인" if v.approved else "거절"
        detail = v.rejection_reason or ""
        if v.approved and v.adjusted_size_pct is not None:
            detail = f"크기 조정 → {v.adjusted_size_pct:.2f}%"
        if v.warnings:
            detail += f"  [경고: {'; '.join(v.warnings)[:60]}]"
        print(f"{label:<42} {verdict:<10} {detail}")

    # Circuit breaker: the layer above the per-order checks.
    print("\n--- 계좌 단위 차단기 (경고 4.5% · 정지 5%) ---")
    for eq in (9800, 9600, 9550, 9400):
        events = breakers.check_all(
            current_equity=eq, peak_equity=EQUITY,
            daily_pnl_pct=(eq / EQUITY - 1), current_atr_pct=0.01,
            avg_atr_pct=0.01, spread_pct=0.0001, funding_rate=0.0,
            ws_seconds_since_update=1.0, llm_consecutive_failures=0)
        allowed, why = breakers.check_trade_allowed()
        fired = ", ".join(f"{e.breaker_type.value}:{e.action.value}"
                          for e in events) or "-"
        print(f"equity {eq:>6}  ({(eq/EQUITY-1)*100:+.1f}%)   발동={fired:<28} "
              f"거래허용={allowed}  {why or ''}")
    v = rm.validate_action(action=act(), equity=9400, open_positions=[],
                           current_prices={SYM: PX}, confidence=0.7)
    print(f"\n차단기 발동 뒤 같은 진입 제안 → 승인={v.approved}  "
          f"{v.rejection_reason or ''}")


if __name__ == "__main__":
    main()
