#!/usr/bin/env python3
"""
TG信号监听器（no_agent模式）：
从Telegram forwarder数据库读取新信号→调advisor脚本→格式化含📐→推QQ

用法: python3 tg_signal_monitor.py
配合cron: */1 * * * * python3 ~/.hermes/skills/trading/okx-auto-position/scripts/tg_signal_monitor.py
"""

import sqlite3
import json
import subprocess
import sys
import os
import re
from pathlib import Path
from datetime import datetime

# Paths
FORWARDER_DB = "/tmp/forward.db"  # TG forwarder DB (docker cp出来)
STATE_FILE = Path.home() / ".hermes/trading/.signal_monitor_state"
SKILL_DIR = Path.home() / ".hermes/skills/trading/okx-auto-position"
ADVISOR_SCRIPT = SKILL_DIR / "scripts" / "okx_position_advisor.py"
FORMAT_SCRIPT = SKILL_DIR / "scripts" / "format_signal.py"
QQ_PUSH = Path.home() / ".hermes/scripts/push_to_qq.sh"
SIGNAL_HISTORY_DB = Path.home() / ".hermes/trading/signal_history.db"

def get_last_msg_id():
    """Read last processed message ID"""
    if STATE_FILE.exists():
        return int(STATE_FILE.read_text().strip())
    return 0

def save_last_msg_id(msg_id):
    """Save last processed message ID"""
    STATE_FILE.parent.mkdir(parents=True, exist_ok=True)
    STATE_FILE.write_text(str(msg_id))

def parse_signal(text):
    """Parse TG signal text, extract key fields"""
    # Extract trader name
    trader_match = re.search(r'【([^】]{1,20})】', text)
    trader = trader_match.group(1) if trader_match else "未知"
    
    # Extract fields
    fields = {}
    patterns = {
        'symbol': r'【币种】\s*[:：]?\s*(\S+)',
        'side': r'【方向】\s*[:：]?\s*(做多|做空)',
        'leverage': r'【杠杆】\s*[:：]?\s*(\d+)',
        'size': r'【仓位大小】\s*[:：]?\s*([\d,.]+)',
        'value': r'【仓位价值】\s*[:：]?\s*\$?\s*([\d,.]+)',
        'entry': r'【开仓价】\s*[:：]?\s*([\d,.]+)',
        'current': r'【当前价】\s*[:：]?\s*([\d,.]+)',
        'pnl': r'【未实现盈亏】\s*[:：]?\s*([-\d,.]+)',
    }
    
    for key, pattern in patterns.items():
        match = re.search(pattern, text)
        if match:
            fields[key] = match.group(1).replace(',', '')
    
    return trader, fields

def classify_signal(fields, current_positions):
    """Classify as A(加仓) or C(新开仓)"""
    symbol = fields.get('symbol', '').replace('USDT', '').replace('/USDT', '').strip()
    for pos in current_positions:
        if symbol.upper() in pos['symbol'].upper():
            return 'A'  # 加仓
    return 'C'  # 新开仓

def run_format_script(fields, trader, signal_type):
    """Run format_signal.py and return the formatted message"""
    symbol = fields.get('symbol', '').replace('USDT', '').replace('/USDT', '').strip()
    side = 'long' if fields.get('side', '').startswith('做多') else 'short'
    leverage = fields.get('leverage', '10')
    size = fields.get('size', '0')
    value = fields.get('value', '$0')
    entry = fields.get('entry', '0')
    pnl = fields.get('pnl', '0')
    
    if not value.startswith('$'):
        value = f'${value}'
    
    cmd = [
        'python3', str(FORMAT_SCRIPT),
        '--symbol', symbol,
        '--side', side,
        '--leverage', leverage,
        '--trader', trader,
        '--trader-pos', f'{size} {symbol}',
        '--trader-value', value,
        '--trader-entry', entry,
        '--trader-pnl', pnl,
        '--signal-type', signal_type,
    ]
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            return f"⚠️ format_signal.py 错误: {result.stderr.strip()}"
    except subprocess.TimeoutExpired:
        return "⚠️ format_signal.py 超时"
    except Exception as e:
        return f"⚠️ 执行错误: {e}"

def push_to_qq(message):
    """Push message to QQ via push_to_qq.sh"""
    try:
        result = subprocess.run(
            ['bash', str(QQ_PUSH), message],
            capture_output=True, text=True, timeout=15
        )
        return result.returncode == 0
    except:
        return False

def log_to_db(trader, symbol, side, leverage, raw_text, outcome='pushed'):
    """Log signal to history database"""
    try:
        conn = sqlite3.connect(str(SIGNAL_HISTORY_DB))
        conn.execute("""
            INSERT INTO signals (timestamp, trader, symbol, side, leverage, raw_text, outcome)
            VALUES (?, ?, ?, ?, ?, ?, ?)
        """, (datetime.now().isoformat(), trader, symbol, side, leverage, raw_text, outcome))
        conn.commit()
        conn.close()
    except:
        pass

def main():
    # Check if forwarder DB exists
    if not Path(FORWARDER_DB).exists():
        # Try to copy from docker
        try:
            subprocess.run(
                ['docker', 'cp', 'telegram-forwarder:/app/db/forward.db', FORWARDER_DB],
                capture_output=True, timeout=10
            )
        except:
            print("❌ 无法获取forwarder DB")
            return
    
    last_id = get_last_msg_id()
    
    try:
        conn = sqlite3.connect(FORWARDER_DB)
        conn.row_factory = sqlite3.Row
        
        # Get new messages from the forwarder
        cursor = conn.execute("""
            SELECT id, message_text, created_at 
            FROM forwarded_messages 
            WHERE id > ? AND chat_id = '-1003966251111'
            ORDER BY id ASC
            LIMIT 10
        """, (last_id,))
        
        messages = cursor.fetchall()
        conn.close()
        
        if not messages:
            return  # No new messages, silent exit
        
        for msg in messages:
            text = msg['message_text'] or ''
            msg_id = msg['id']
            
            # Skip non-signal messages
            if '【币种】' not in text and '【方向】' not in text:
                save_last_msg_id(msg_id)
                continue
            
            # Parse signal
            trader, fields = parse_signal(text)
            
            if not fields.get('symbol') or not fields.get('side'):
                save_last_msg_id(msg_id)
                continue
            
            # Classify (simplified - always treat as new for now)
            signal_type = 'C'
            
            # Run format_signal.py
            message = run_format_script(fields, trader, signal_type)
            
            if message and '⚠️' not in message:
                # Push to QQ
                success = push_to_qq(message)
                
                # Log to DB
                symbol = fields.get('symbol', '').replace('USDT', '').strip()
                side = 'long' if fields.get('side', '').startswith('做多') else 'short'
                log_to_db(trader, symbol, side, fields.get('leverage', '10'), text, 
                         'pushed' if success else 'push_failed')
            
            save_last_msg_id(msg_id)
    
    except sqlite3.OperationalError as e:
        print(f"❌ DB错误: {e}")
    except Exception as e:
        print(f"❌ 错误: {e}")

if __name__ == '__main__':
    main()
