#!/usr/bin/env python3
"""
从 position_snapshots 重建历史交易记录，补录到 trading_ledger.ndjson

用法: python3 bridge/recover_ledger_from_snapshots.py --date 2026-03-25 --dry-run
"""
import json, sys, pathlib, argparse
from datetime import datetime, timezone
from collections import defaultdict

# ROOT now resolved via frozen_path (PyInstaller-safe)
from frozen_path import APP_ROOT as ROOT
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "bridge"))
import config_manager

LOG_DIR = config_manager.get_logs_dir()
SNAPSHOT_DIR = LOG_DIR / "position_snapshots"
TRADE_LEDGER = LOG_DIR / "trading_ledger.ndjson"

def parse_ts(filename):
    # snapshot_YYYYMMDD_HHMM.json -> datetime
    parts = filename.replace("snapshot_", "").replace(".json", "")
    date_str = parts[:8]
    time_str = parts[9:13]
    return datetime.strptime(f"{date_str}_{time_str}", "%Y%m%d_%H%M")

def load_snapshots(date_str):
    """加载指定日期的所有快照"""
    pattern = f"snapshot_{date_str.replace('-', '')}_*.json"
    files = sorted(SNAPSHOT_DIR.glob(pattern))
    snaps = []
    for f in files:
        with open(f, encoding="utf-8") as fp:
            snaps.append(json.load(fp))
    return snaps

def recover_trades(snaps):
    """从快照序列恢复开仓/平仓事件"""
    events = []  # (timestamp, event_type, ticket, side, entry, volume, sl, tp)
    
    prev_tickets = []
    
    for snap in snaps:
        ts_str = snap["timestamp"]
        ts = datetime.fromisoformat(ts_str.replace("Z", "+00:00"))
        positions = snap.get("positions", [])
        tickets = [p["ticket"] for p in positions]
        
        # 平仓：之前有，现在没了
        closed = set(prev_tickets) - set(tickets)
        for t in closed:
            # 找开仓事件
            open_ev = next((e for e in events if e[2] == t and e[1] == "OPEN"), None)
            if open_ev:
                events.append((ts_str, "CLOSE", t, open_ev[3], open_ev[4], open_ev[5], open_ev[6], open_ev[7]))
        
        # 开仓：新出现
        opened = set(tickets) - set(prev_tickets)
        for p in positions:
            if p["ticket"] in opened:
                events.append((ts_str, "OPEN", p["ticket"], p["side"], p["entry"],
                               p["volume"], p["sl"], p["tp"]))
        
        prev_tickets = tickets
    
    return events

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--date", required=True, help="日期如 2026-03-25")
    parser.add_argument("--dry-run", action="store_true", help="不写入，只显示")
    args = parser.parse_args()
    
    date_str = args.date
    print(f"正在从快照重建 {date_str} 的交易记录...")
    
    snaps = load_snapshots(date_str)
    print(f"加载了 {len(snaps)} 个快照")
    
    events = recover_trades(snaps)
    opens = [e for e in events if e[1] == "OPEN"]
    closes = [e for e in events if e[1] == "CLOSE"]
    print(f"重建结果: {len(opens)} 笔开仓, {len(closes)} 笔平仓")
    
    for e in events:
        print(f"  [{e[0]}] {e[1]:5s} ticket={e[2]} {e[3]} entry={e[4]}")
    
    if args.dry_run:
        print("\n=== DRY RUN: 不写入 ===")
        return
    
    # 写入 ledger（仅平仓事件，因为开仓时尚未知道盈亏）
    # 注意：PnL 缺失，只能写 pnl=0，需要后续用收盘价补充
    from skill_trading_memory import append_trade, _ndjson_append
    
    close_events = [e for e in events if e[1] == "CLOSE"]
    for e in close_events:
        ts_str, _, ticket, side, entry, volume, sl, tp = e
        rec = {
            "ticket": ticket,
            "side": side,
            "entry": entry,
            "exit": 0,  # TODO: 需要历史价格补充
            "pnl": 0,
            "volume": volume,
            "duration_min": 0,  # TODO: 计算
            "session": "RECOVERED",
            "regime": "UNKNOWN",
            "confidence": 0,
            "strategy": "RECOVERED",
            "sl_hit": False,
            "tp_hit": False,
            "sl_price": sl,
            "tp_price": tp,
            "ts": ts_str,
            "_recovered": True,
        }
        _ndjson_append(TRADE_LEDGER, rec)
        print(f"  写入 ledger: ticket={ticket}")
    
    print(f"\n完成: {len(close_events)} 笔记交易已写入 trading_ledger.ndjson")

if __name__ == "__main__":
    main()
