#!/usr/bin/env python3
"""7/9 SHORT 종목일일손익게이트 백테 검증 — Case A(edge=2000) vs B(edge=0)."""
from __future__ import annotations

import sys
import traceback
from collections import defaultdict
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from database import TradeDB
from kis_trader.engine import tail_engine as te
from kis_trader.backtest import tail_backtest_common as tbc
from kis_trader.engine.tail_tick_replay import tail_backtest_wants_tick_replay


def _summarize(trades, label: str) -> dict:
    total = len(trades)
    wins = [t for t in trades if float(t.get("pnl") or 0) > 0]
    pnl = sum(float(t.get("pnl") or 0) for t in trades)
    by_code: dict = defaultdict(list)
    for t in trades:
        by_code[t.get("code")].append(t)
    multi = sum(1 for v in by_code.values() if len(v) > 1)
    wr = (len(wins) / total * 100) if total else 0.0
    print(
        f"  trades={total} wins={len(wins)} WR={wr:.1f}% "
        f"pnl={pnl:+,.0f} multi_codes={multi}",
        flush=True,
    )
    for code, ts in sorted(by_code.items()):
        cum = 0.0
        parts = []
        for t in ts:
            cum += float(t.get("pnl") or 0)
            hm = str(t.get("entry_time") or t.get("candle_time") or "")[8:12]
            parts.append(
                f"{hm}:{t.get('pnl', 0):+.0f}({t.get('exit_reason', '')})→cum{cum:+.0f}"
            )
        if len(ts) > 1:
            print(f"  [{code}] " + " | ".join(parts), flush=True)
    return {"label": label, "trades": total, "pnl": pnl, "multi": multi}


def main() -> int:
    print("=== 7/9 SHORT 게이트 백테 검증 (skip_hts=DB) ===", flush=True)
    db = TradeDB()
    start, end = "2026-07-09", "2026-07-09"
    start_key = start.replace("-", "") + "0000"
    end_key = end.replace("-", "") + "2359"
    start_ymd, end_ymd = start_key[:8], end_key[:8]

    try:
        base = te.get_tail_defaults_from_db(db)
        skip_hts = bool(base.get("skip_hts_scan_dupes"))
        print(f"skip_hts_scan_dupes(DB)={skip_hts}", flush=True)

        universe, src, n_slots, _ = tbc.resolve_tail_universe(
            start_ymd, end_ymd, use_saved_history=True, strategy_id="SHORT",
        )
        tf = int(base.get("timeframe") or 3)
        rsi = int(base.get("rsi_period") or 14)
        candles_by_code, _, _ = tbc.load_tail_candles_by_code(
            db, start_key, end_key, tf, rsi_period=rsi,
        )
        codes = len(candles_by_code)
        bars = sum(len(v) for v in candles_by_code.values())
        slot = float(base.get("slot_money") or 300000)
        budget = float(base.get("total_budget_krw") or slot * int(base.get("max_stocks") or 4))
        print(
            f"[로드] universe={src} slots={n_slots} codes={codes} bars={bars} "
            f"slot={slot} budget={budget}",
            flush=True,
        )

        fee = float(base.get("fee_rate") or 0.00015)
        tax = float(base.get("sell_tax") or 0.0023)
        meta = {"db": db, "start_key": start_key, "end_key": end_key}
        use_tick = tail_backtest_wants_tick_replay(base)
        print(f"[로드] tick_replay={use_tick}", flush=True)

        cases = [
            ("A GATE_ON edge=2000", 30000.0, 1.5, 2000.0),
            ("B GATE_ON edge=0", 30000.0, 1.5, 0.0),
        ]
        results = []
        for label, krw, pct, edge in cases:
            params = dict(base)
            params["symbol_daily_loss_limit_krw"] = krw
            params["symbol_daily_loss_limit_pct"] = pct
            params["reentry_min_edge_krw"] = edge
            params["skip_hts_scan_dupes"] = skip_hts
            print(
                f"\n--- {label}: krw={krw} pct={pct} edge={edge} ---",
                flush=True,
            )
            trades = tbc.run_tail_backtest_web_aligned(
                candles_by_code,
                params,
                universe,
                slot_money=slot,
                fee_rate=fee,
                sell_tax=tax,
                total_budget_krw=budget,
                meta_out=meta,
            )
            results.append(_summarize(trades, label))

        print("\n======== SUMMARY ========", flush=True)
        for r in results:
            print(f"  {r['label']}: trades={r['trades']} pnl={r['pnl']:+,.0f} multi={r['multi']}", flush=True)
        print("\n[LIVE 7/9] trades=3(신규2) pnl=-7,053 (376980 전일포지션 포함)", flush=True)
        print("✅ VERIFY DONE", flush=True)
        return 0
    except Exception:
        traceback.print_exc()
        return 1
    finally:
        db.close()


if __name__ == "__main__":
    raise SystemExit(main())
