"""
智能盯盘 - 数据库模块
记录AI决策、交易记录、监控配置等
"""

import sqlite3
import logging
from typing import Dict, List, Optional
from datetime import datetime
import json


class SmartMonitorDB:
    """智能盯盘数据库"""
    
    def __init__(self, db_file: str = 'smart_monitor.db'):
        """
        初始化数据库
        
        Args:
            db_file: 数据库文件路径
        """
        self.db_file = db_file
        self.logger = logging.getLogger(__name__)
        self._init_database()
    
    def _init_database(self):
        """初始化数据库表结构"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        # 1. 监控任务表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS monitor_tasks (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                task_name TEXT NOT NULL,
                stock_code TEXT NOT NULL,
                stock_name TEXT,
                enabled INTEGER DEFAULT 1,
                check_interval INTEGER DEFAULT 300,
                auto_trade INTEGER DEFAULT 0,
                position_size_pct REAL DEFAULT 20,
                stop_loss_pct REAL DEFAULT 5,
                take_profit_pct REAL DEFAULT 10,
                qmt_account_id TEXT,
                notify_email TEXT,
                notify_webhook TEXT,
                has_position INTEGER DEFAULT 0,
                position_cost REAL DEFAULT 0,
                position_quantity INTEGER DEFAULT 0,
                position_date TEXT,
                created_at TEXT DEFAULT CURRENT_TIMESTAMP,
                updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(stock_code)
            )
        ''')
        
        # 添加持仓相关字段（如果表已存在但缺少这些字段）
        try:
            cursor.execute("ALTER TABLE monitor_tasks ADD COLUMN has_position INTEGER DEFAULT 0")
        except sqlite3.OperationalError:
            pass
        
        try:
            cursor.execute("ALTER TABLE monitor_tasks ADD COLUMN position_cost REAL DEFAULT 0")
        except sqlite3.OperationalError:
            pass
        
        try:
            cursor.execute("ALTER TABLE monitor_tasks ADD COLUMN position_quantity INTEGER DEFAULT 0")
        except sqlite3.OperationalError:
            pass
        
        try:
            cursor.execute("ALTER TABLE monitor_tasks ADD COLUMN position_date TEXT")
        except sqlite3.OperationalError:
            pass
        
        # 2. AI决策记录表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS ai_decisions (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                stock_code TEXT NOT NULL,
                stock_name TEXT,
                decision_time TEXT NOT NULL,
                trading_session TEXT,
                action TEXT NOT NULL,
                confidence INTEGER,
                reasoning TEXT,
                position_size_pct REAL,
                stop_loss_pct REAL,
                take_profit_pct REAL,
                risk_level TEXT,
                key_price_levels TEXT,
                market_data TEXT,
                account_info TEXT,
                executed INTEGER DEFAULT 0,
                execution_result TEXT,
                created_at TEXT DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # 3. 交易记录表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS trade_records (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                stock_code TEXT NOT NULL,
                stock_name TEXT,
                trade_type TEXT NOT NULL,
                quantity INTEGER,
                price REAL,
                amount REAL,
                order_id TEXT,
                order_status TEXT,
                ai_decision_id INTEGER,
                trade_time TEXT NOT NULL,
                commission REAL DEFAULT 0,
                tax REAL DEFAULT 0,
                profit_loss REAL DEFAULT 0,
                created_at TEXT DEFAULT CURRENT_TIMESTAMP,
                FOREIGN KEY(ai_decision_id) REFERENCES ai_decisions(id)
            )
        ''')
        
        # 4. 持仓监控表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS position_monitor (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                stock_code TEXT NOT NULL,
                stock_name TEXT,
                quantity INTEGER,
                cost_price REAL,
                current_price REAL,
                profit_loss REAL,
                profit_loss_pct REAL,
                holding_days INTEGER,
                buy_date TEXT,
                stop_loss_price REAL,
                take_profit_price REAL,
                last_check_time TEXT,
                status TEXT DEFAULT 'holding',
                created_at TEXT DEFAULT CURRENT_TIMESTAMP,
                updated_at TEXT DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(stock_code)
            )
        ''')
        
        # 5. 通知记录表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS notifications (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                stock_code TEXT,
                notify_type TEXT NOT NULL,
                notify_target TEXT,
                subject TEXT,
                content TEXT,
                status TEXT DEFAULT 'pending',
                error_msg TEXT,
                sent_at TEXT,
                created_at TEXT DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        # 6. 系统日志表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS system_logs (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                log_level TEXT,
                module TEXT,
                message TEXT,
                details TEXT,
                created_at TEXT DEFAULT CURRENT_TIMESTAMP
            )
        ''')
        
        conn.commit()
        conn.close()
        self.logger.info(f"数据库初始化完成: {self.db_file}")
    
    # ========== 监控任务管理 ==========
    
    def add_monitor_task(self, task_data: Dict) -> int:
        """添加监控任务"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            INSERT INTO monitor_tasks 
            (task_name, stock_code, stock_name, enabled, check_interval, 
             auto_trade, position_size_pct, stop_loss_pct, take_profit_pct,
             qmt_account_id, notify_email, notify_webhook,
             has_position, position_cost, position_quantity, position_date)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (
            task_data.get('task_name'),
            task_data.get('stock_code'),
            task_data.get('stock_name'),
            task_data.get('enabled', 1),
            task_data.get('check_interval', 300),
            task_data.get('auto_trade', 0),
            task_data.get('position_size_pct', 20),
            task_data.get('stop_loss_pct', 5),
            task_data.get('take_profit_pct', 10),
            task_data.get('qmt_account_id'),
            task_data.get('notify_email'),
            task_data.get('notify_webhook'),
            task_data.get('has_position', 0),
            task_data.get('position_cost', 0),
            task_data.get('position_quantity', 0),
            task_data.get('position_date')
        ))
        
        task_id = cursor.lastrowid
        conn.commit()
        conn.close()
        
        position_info = f"（持仓: {task_data.get('position_quantity')}股 @ {task_data.get('position_cost')}元）" if task_data.get('has_position') else ""
        self.logger.info(f"添加监控任务: {task_data.get('stock_code')} - {task_data.get('task_name')} {position_info}")
        return task_id
    
    def get_monitor_tasks(self, enabled_only: bool = True) -> List[Dict]:
        """获取监控任务列表"""
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        if enabled_only:
            cursor.execute('SELECT * FROM monitor_tasks WHERE enabled = 1 ORDER BY id DESC')
        else:
            cursor.execute('SELECT * FROM monitor_tasks ORDER BY id DESC')
        
        rows = cursor.fetchall()
        conn.close()
        
        return [dict(row) for row in rows]
    
    def update_monitor_task(self, task_id: int, updates: Dict):
        """更新监控任务"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        set_clause = ', '.join([f"{k} = ?" for k in updates.keys()])
        values = list(updates.values()) + [task_id]
        
        cursor.execute(f'''
            UPDATE monitor_tasks 
            SET {set_clause}, updated_at = CURRENT_TIMESTAMP
            WHERE id = ?
        ''', values)
        
        conn.commit()
        conn.close()
    
    def update_monitor_task(self, stock_code: str, task_data: Dict):
        """更新监控任务"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        # 构建更新语句
        update_fields = []
        values = []
        
        if 'task_name' in task_data:
            update_fields.append('task_name = ?')
            values.append(task_data['task_name'])
        
        if 'check_interval' in task_data:
            update_fields.append('check_interval = ?')
            values.append(task_data['check_interval'])
        
        if 'auto_trade' in task_data:
            update_fields.append('auto_trade = ?')
            values.append(task_data['auto_trade'])
        
        if 'position_size_pct' in task_data:
            update_fields.append('position_size_pct = ?')
            values.append(task_data['position_size_pct'])
        
        if 'has_position' in task_data:
            update_fields.append('has_position = ?')
            values.append(task_data['has_position'])
        
        if 'position_cost' in task_data:
            update_fields.append('position_cost = ?')
            values.append(task_data['position_cost'])
        
        if 'position_quantity' in task_data:
            update_fields.append('position_quantity = ?')
            values.append(task_data['position_quantity'])
        
        if 'position_date' in task_data:
            update_fields.append('position_date = ?')
            values.append(task_data['position_date'])
        
        if 'notify_email' in task_data:
            update_fields.append('notify_email = ?')
            values.append(task_data['notify_email'])
        
        # 添加更新时间
        update_fields.append('updated_at = CURRENT_TIMESTAMP')
        
        # 添加WHERE条件
        values.append(stock_code)
        
        sql = f"UPDATE monitor_tasks SET {', '.join(update_fields)} WHERE stock_code = ?"
        cursor.execute(sql, values)
        
        conn.commit()
        conn.close()
        
        self.logger.info(f"更新监控任务: {stock_code}")
    
    def delete_monitor_task(self, task_id: int):
        """删除监控任务"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('DELETE FROM monitor_tasks WHERE id = ?', (task_id,))
        
        conn.commit()
        conn.close()
    
    # ========== AI决策记录 ==========
    
    def save_ai_decision(self, decision_data: Dict) -> int:
        """保存AI决策"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            INSERT INTO ai_decisions
            (stock_code, stock_name, decision_time, trading_session,
             action, confidence, reasoning, position_size_pct,
             stop_loss_pct, take_profit_pct, risk_level,
             key_price_levels, market_data, account_info)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (
            decision_data.get('stock_code'),
            decision_data.get('stock_name'),
            decision_data.get('decision_time', datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
            decision_data.get('trading_session'),
            decision_data.get('action'),
            decision_data.get('confidence'),
            decision_data.get('reasoning'),
            decision_data.get('position_size_pct'),
            decision_data.get('stop_loss_pct'),
            decision_data.get('take_profit_pct'),
            decision_data.get('risk_level'),
            json.dumps(decision_data.get('key_price_levels', {})),
            json.dumps(decision_data.get('market_data', {})),
            json.dumps(decision_data.get('account_info', {}))
        ))
        
        decision_id = cursor.lastrowid
        conn.commit()
        conn.close()
        
        return decision_id
    
    def get_ai_decisions(self, stock_code: str = None, limit: int = 100) -> List[Dict]:
        """获取AI决策历史"""
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        if stock_code:
            cursor.execute('''
                SELECT * FROM ai_decisions 
                WHERE stock_code = ? 
                ORDER BY decision_time DESC 
                LIMIT ?
            ''', (stock_code, limit))
        else:
            cursor.execute('''
                SELECT * FROM ai_decisions 
                ORDER BY decision_time DESC 
                LIMIT ?
            ''', (limit,))
        
        rows = cursor.fetchall()
        conn.close()
        
        decisions = []
        for row in rows:
            d = dict(row)
            # 解析JSON字段
            d['key_price_levels'] = json.loads(d['key_price_levels']) if d['key_price_levels'] else {}
            d['market_data'] = json.loads(d['market_data']) if d['market_data'] else {}
            d['account_info'] = json.loads(d['account_info']) if d['account_info'] else {}
            decisions.append(d)
        
        return decisions
    
    def update_decision_execution(self, decision_id: int, executed: bool, result: str):
        """更新决策执行状态"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            UPDATE ai_decisions 
            SET executed = ?, execution_result = ?
            WHERE id = ?
        ''', (1 if executed else 0, result, decision_id))
        
        conn.commit()
        conn.close()
    
    # ========== 交易记录 ==========
    
    def save_trade_record(self, trade_data: Dict) -> int:
        """保存交易记录"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            INSERT INTO trade_records
            (stock_code, stock_name, trade_type, quantity, price, amount,
             order_id, order_status, ai_decision_id, trade_time,
             commission, tax, profit_loss)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ''', (
            trade_data.get('stock_code'),
            trade_data.get('stock_name'),
            trade_data.get('trade_type'),
            trade_data.get('quantity'),
            trade_data.get('price'),
            trade_data.get('amount'),
            trade_data.get('order_id'),
            trade_data.get('order_status'),
            trade_data.get('ai_decision_id'),
            trade_data.get('trade_time', datetime.now().strftime('%Y-%m-%d %H:%M:%S')),
            trade_data.get('commission', 0),
            trade_data.get('tax', 0),
            trade_data.get('profit_loss', 0)
        ))
        
        record_id = cursor.lastrowid
        conn.commit()
        conn.close()
        
        return record_id
    
    def get_trade_records(self, stock_code: str = None, limit: int = 100) -> List[Dict]:
        """获取交易记录"""
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        if stock_code:
            cursor.execute('''
                SELECT * FROM trade_records 
                WHERE stock_code = ? 
                ORDER BY trade_time DESC 
                LIMIT ?
            ''', (stock_code, limit))
        else:
            cursor.execute('''
                SELECT * FROM trade_records 
                ORDER BY trade_time DESC 
                LIMIT ?
            ''', (limit,))
        
        rows = cursor.fetchall()
        conn.close()
        
        return [dict(row) for row in rows]
    
    # ========== 持仓监控 ==========
    
    def save_position(self, position_data: Dict):
        """保存/更新持仓信息"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        # 检查是否已存在
        cursor.execute('SELECT id FROM position_monitor WHERE stock_code = ?', 
                      (position_data.get('stock_code'),))
        existing = cursor.fetchone()
        
        if existing:
            # 更新
            cursor.execute('''
                UPDATE position_monitor
                SET stock_name = ?, quantity = ?, cost_price = ?,
                    current_price = ?, profit_loss = ?, profit_loss_pct = ?,
                    holding_days = ?, stop_loss_price = ?, take_profit_price = ?,
                    last_check_time = ?, updated_at = CURRENT_TIMESTAMP
                WHERE stock_code = ?
            ''', (
                position_data.get('stock_name'),
                position_data.get('quantity'),
                position_data.get('cost_price'),
                position_data.get('current_price'),
                position_data.get('profit_loss'),
                position_data.get('profit_loss_pct'),
                position_data.get('holding_days'),
                position_data.get('stop_loss_price'),
                position_data.get('take_profit_price'),
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                position_data.get('stock_code')
            ))
        else:
            # 插入
            cursor.execute('''
                INSERT INTO position_monitor
                (stock_code, stock_name, quantity, cost_price, current_price,
                 profit_loss, profit_loss_pct, holding_days, buy_date,
                 stop_loss_price, take_profit_price, last_check_time, status)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                position_data.get('stock_code'),
                position_data.get('stock_name'),
                position_data.get('quantity'),
                position_data.get('cost_price'),
                position_data.get('current_price'),
                position_data.get('profit_loss'),
                position_data.get('profit_loss_pct'),
                position_data.get('holding_days'),
                position_data.get('buy_date'),
                position_data.get('stop_loss_price'),
                position_data.get('take_profit_price'),
                datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'holding'
            ))
        
        conn.commit()
        conn.close()
    
    def get_positions(self) -> List[Dict]:
        """获取所有持仓"""
        conn = sqlite3.connect(self.db_file)
        conn.row_factory = sqlite3.Row
        cursor = conn.cursor()
        
        cursor.execute('SELECT * FROM position_monitor WHERE status = "holding" ORDER BY id DESC')
        
        rows = cursor.fetchall()
        conn.close()
        
        return [dict(row) for row in rows]
    
    def close_position(self, stock_code: str):
        """关闭持仓记录"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            UPDATE position_monitor 
            SET status = 'closed', updated_at = CURRENT_TIMESTAMP
            WHERE stock_code = ?
        ''', (stock_code,))
        
        conn.commit()
        conn.close()
    
    # ========== 通知记录 ==========
    
    def save_notification(self, notify_data: Dict) -> int:
        """保存通知记录"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            INSERT INTO notifications
            (stock_code, notify_type, notify_target, subject, content, status)
            VALUES (?, ?, ?, ?, ?, ?)
        ''', (
            notify_data.get('stock_code'),
            notify_data.get('notify_type'),
            notify_data.get('notify_target'),
            notify_data.get('subject'),
            notify_data.get('content'),
            notify_data.get('status', 'pending')
        ))
        
        notify_id = cursor.lastrowid
        conn.commit()
        conn.close()
        
        return notify_id
    
    def update_notification_status(self, notify_id: int, status: str, error_msg: str = None):
        """更新通知状态"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            UPDATE notifications 
            SET status = ?, error_msg = ?, sent_at = CURRENT_TIMESTAMP
            WHERE id = ?
        ''', (status, error_msg, notify_id))
        
        conn.commit()
        conn.close()
    
    # ========== 系统日志 ==========
    
    def log_system_event(self, level: str, module: str, message: str, details: str = None):
        """记录系统日志"""
        conn = sqlite3.connect(self.db_file)
        cursor = conn.cursor()
        
        cursor.execute('''
            INSERT INTO system_logs (log_level, module, message, details)
            VALUES (?, ?, ?, ?)
        ''', (level, module, message, details))
        
        conn.commit()
        conn.close()


if __name__ == '__main__':
    # 测试数据库
    logging.basicConfig(level=logging.INFO)
    
    db = SmartMonitorDB('test_smart_monitor.db')
    
    # 测试添加监控任务
    task_id = db.add_monitor_task({
        'task_name': '茅台盯盘',
        'stock_code': '600519',
        'stock_name': '贵州茅台',
        'auto_trade': 1,
        'notify_email': 'test@example.com'
    })
    
    print(f"创建监控任务 ID: {task_id}")
    
    # 获取任务列表
    tasks = db.get_monitor_tasks()
    print(f"\n监控任务列表: {len(tasks)}个")
    for task in tasks:
        print(f"  - {task['stock_code']} {task['stock_name']}")

