#!/usr/bin/env python3
"""
Trade Insight Logger - 自动从平仓记录中提炼经验写入记忆
输出到 memory/trading-log-YYYY-MM.md，供梦境系统自动晋升
"""
import sys, json, pathlib, re
from datetime import datetime, timedelta

# ROOT now resolved via frozen_path (PyInstaller-safe)
from frozen_path import APP_ROOT as ROOT
MEMORY_DIR = ROOT / "memory"
LEDGER = ROOT / "logs" / "trading_ledger.ndjson"
STATE_FILE = ROOT / "logs" / ".trade_insight_state.json"

MEMORY_DIR.mkdir(exist_ok=True)

def load_state():
    if STATE_FILE.exists():
        with open(STATE_FILE, encoding="utf-8") as f:
            return json.load(f)
    return {"last_processed_ts": None, "processed_tickets": []}

def save_state(state):
    with open(STATE_FILE, "w", encoding="utf-8") as f:
        json.dump(state, f, indent=2)

def get_memory_file():
    now = datetime.now()
    return MEMORY_DIR / f"trading-log-{now.strftime('%Y-%m')}.md"

def classify_insight(side, entry, exit_price, regime, duration_min, strategy):
    """根据交易数据提炼关键洞察"""
    insights = []

    if regime in ["RANGING", "UNCERTAIN"]:
        insights.append("震荡市场(UNCERTAIN/RANGING)下持仓超过30分钟需特别谨慎")

    if strategy == "EMA_CROSS":
        insights.append("EMA_CROSS在TRENDING时表现较好，UNCERTAIN时信号杂")

    if duration_min and duration_min > 60:
        insights.append(f"长线持仓({duration_min}min)需注意隔夜跳空风险")

    if regime == "BREAKOUT":
        insights.append("BREAKOUT策略需配合成交量确认，假突破概率高")

    return insights

def format_trade_entry(trade, insights, now):
    ts = trade.get("ts", "")
    ticket = trade.get("ticket", "?")
    side = trade.get("side", "?")
    regime = trade.get("regime", "?")
    strategy = trade.get("strategy", "?")
    duration = trade.get("duration_min", 0)
    pnl = trade.get("pnl", 0)

    entry = trade.get("entry", 0)
    exit_price = trade.get("exit", 0)
    if entry and exit_price:
        ret = ((exit_price - entry) / entry) * 100 if side == "BUY" else ((entry - exit_price) / entry) * 100
    else:
        ret = 0

    insight_text = "; ".join(insights) if insights else "常规持仓"

    return f"""## Trade {ticket} | {ts[:10]} {ts[11:19]} UTC

- **方向**: {side} | **Regime**: {regime} | **策略**: {strategy}
- **入场**: {entry:.2f} → **出场**: {exit_price:.2f} | **回报**: {ret:.2f}%
- **持仓时长**: {duration}min | **PnL**: ${pnl:.2f}
- **经验**: {insight_text}
"""

def run():
    state = load_state()
    processed = set(state.get("processed_tickets", []))

    if not LEDGER.exists():
        print("No trading ledger found")
        return

    # Read all closed trades
    closed_trades = []
    with open(LEDGER, encoding="utf-8") as f:
        for line in f:
            try:
                trade = json.loads(line.strip())
                if trade.get("action") in ["CLOSE", "CLOSED"] and trade.get("status") == "FILLED":
                    closed_trades.append(trade)
            except:
                continue

    # Sort by timestamp descending
    closed_trades.sort(key=lambda t: t.get("ts", ""), reverse=True)

    # Find new trades
    new_trades = [t for t in closed_trades if str(t.get("ticket", "")) not in processed]

    if not new_trades:
        print(f"[{datetime.now().strftime('%H:%M:%S')}] No new closed trades to process")
        return

    # Limit to last 10 per run
    new_trades = new_trades[:10]

    memory_file = get_memory_file()
    existing = memory_file.read_text(encoding="utf-8") if memory_file.exists() else ""

    entries_added = 0
    for trade in reversed(new_trades):  # Oldest first
        ticket = str(trade.get("ticket", ""))
        ts = trade.get("ts", "")
        regime = trade.get("regime", "?")
        side = trade.get("side", "?")
        strategy = trade.get("strategy", "?")
        duration = trade.get("duration_min", 0)
        entry = trade.get("entry", 0)
        exit_price = trade.get("exit", 0)

        insights = classify_insight(side, entry, exit_price, regime, duration, strategy)

        # Build structured entry
        entry_text = format_trade_entry(trade, insights, datetime.now())
        existing += "\n" + entry_text

        processed.add(ticket)
        entries_added += 1

    # Write back
    memory_file.write_text(existing.strip())
    state["processed_tickets"] = list(processed)[-500:]  # Keep last 500
    if new_trades:
        state["last_processed_ts"] = new_trades[0].get("ts", None)
    save_state(state)

    print(f"[{datetime.now().strftime('%H:%M:%S')}] [OK] Logged {entries_added} trades to {memory_file.name}")

    # Print brief summary
    summary = []
    for t in new_trades:
        summary.append(f"  Ticket {t.get('ticket')}: {t.get('side')} {t.get('regime')} PnL=${t.get('pnl',0):.2f}")
    print("\n".join(summary[:5]))

if __name__ == "__main__":
    run()
