#!/usr/bin/env python3
"""promote_candidates.py — 自动提拔候选股入自选

从 candidates 表读未提拔的候选，评估后自动加入 holding_strategies。
"""
import sys, json, sqlite3
from pathlib import Path
from datetime import datetime

DB_PATH = Path("/home/hmo/MoFin/data/mofin.db")

def main():
    conn = sqlite3.connect(str(DB_PATH))
    conn.row_factory = sqlite3.Row
    
    # 读未提拔候选（按评分降序）
    rows = conn.execute("""
        SELECT c.code, c.name, c.score_final, c.entry_range, c.stop_loss, c.target
        FROM candidates c
        WHERE (c.promoted IS NULL OR c.promoted = 0)
        AND (c.dropped IS NULL OR c.dropped = 0)
        AND c.score_final >= 4
        ORDER BY c.score_final DESC
    """).fetchall()
    
    if not rows:
        print("[PROMOTE] 无待提拔候选")
        conn.close()
        return
    
    promoted = 0
    for r in rows:
        code = str(r[0])
        name = r[1] or code
        score = r[2] or 0
        entry_range = r[3] or ""
        sl = r[4] or 0
        tp = r[5] or 0
        
        # 解析 entry_range
        el, eh = 0, 0
        if "~" in entry_range:
            parts = entry_range.split("~")
            try:
                el = float(parts[0])
                eh = float(parts[1])
            except: pass
        
        # 查是否已在 holding_strategies
        exists = conn.execute(
            "SELECT id FROM holding_strategies WHERE code=? AND status='active'",
            (code,)
        ).fetchone()
        if exists:
            conn.execute("UPDATE candidates SET promoted=1 WHERE code=?", (code,))
            print(f"  ⏭ {code} {name} 已在自选中，标记promoted")
            continue
        
        # 验证实时价格：无有效价格的候选股不入自选（防假数据污染）
        try:
            import subprocess, json as _jj
            _r = subprocess.run(["python3", "/home/hmo/.hermes/profiles/position-analyst/scripts/stock_quote.py", code],
                               capture_output=True, text=True, timeout=10)
            _q = _jj.loads(_r.stdout)
            if float(_q.get("price", 0)) <= 0:
                print(f"  ⏭ {code} {name} 无实时价格，跳过")
                continue
        except Exception as _e:
            print(f"  ⏭ {code} {name} 价格获取失败({_e})，跳过")
            continue
        
        # 构建策略
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        timing_signal = "买入" if score >= 7 else "关注"
        price_est = (el + eh) / 2 if el > 0 and eh > 0 else 0
        reason_text = []
        if el > 0: reason_text.append(f"买{el}~{eh}")
        if sl > 0: reason_text.append(f"损{sl}")
        if tp > 0: reason_text.append(f"盈{tp}")
        if sl > 0 and tp > 0 and price_est > 0:
            rr = (tp - price_est) / (price_est - sl) if (price_est - sl) > 0 else 0
            reason_text.append(f"RR{rr:.1f}")
        reason_text.append(f"评分{score}")
        action = " | ".join(reason_text) if reason_text else f"市场扫描发现(评分{score})"
        
        conn.execute("""
            INSERT INTO holding_strategies 
            (code, name, price, entry_low, entry_high, stop_loss, take_profit,
             timing_signal, action, decision_type, strategy_type, status,
             rr_ratio, stock_category, created_at, updated_at,
             sector_context, quality_check)
            VALUES (?,?,?,?,?,?,?,?,?,'自选策略','scan',
                    'active',0,'关注',?,?,'', 'pending')
        """, (code, name, 0, el, eh, sl, tp, timing_signal, action, now, now))
        
        conn.execute("UPDATE candidates SET promoted=1 WHERE code=?", (code,))
        promoted += 1
        print(f"  ✅ {code} {name} 评分{score} → 已加入自选({timing_signal})", flush=True)
        
        # 触发全量重评（生成完整9维策略）
        try:
            import subprocess as _sp
            r = _sp.run(["python3", "/home/hmo/MoFin/scripts/per_stock_reassess.py", code],
                       capture_output=True, text=True, timeout=60)
            if r.returncode == 0:
                print(f"    重评完成", flush=True)
            else:
                print(f"    重评失败: {r.stderr.strip()[:100]}", flush=True)
        except Exception as e:
            print(f"    重评异常: {e}", flush=True)
    
    conn.commit()
    print(f"\n[PROMOTE] 本次提拔{promoted}只", flush=True)
    
    # 推XMPP
    if promoted > 0:
        try:
            import urllib.request
            msg = f"📈 自动提拔{promoted}只候选入自选"
            payload = json.dumps({"to": "hmo@yoin.fun", "body": msg, "type": "chat"}).encode()
            req = urllib.request.Request("http://127.0.0.1:5805/", data=payload,
                                        headers={"Content-Type": "application/json"})
            urllib.request.urlopen(req, timeout=5)
        except Exception:
            pass
    
    conn.close()

if __name__ == "__main__":
    main()
