# 数据存储模块
import sqlite3
import json
import os
from datetime import datetime
from typing import Dict, Optional, List
import pandas as pd
from qihuo_analyzer.utils.config_manager import config_manager


class DataStorage:
    """数据存储管理器"""
    
    def __init__(self):
        self.db_path = config_manager.db_path
        self._init_database()
    
    def _init_database(self):
        """初始化数据库"""
        # 确保数据库目录存在
        db_dir = os.path.dirname(self.db_path)
        if db_dir and not os.path.exists(db_dir):
            os.makedirs(db_dir)
        
        # 连接数据库
        conn = sqlite3.connect(self.db_path)
        cursor = conn.cursor()
        
        # 创建表
        # 分析结果表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS analysis_results (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT NOT NULL,
            timestamp TEXT NOT NULL,
            trend TEXT,
            probability REAL,
            direction TEXT,
            cycle TEXT,
            atr REAL,
            adx REAL,
            support REAL,
            resistance REAL,
            stop_loss REAL,
            target_price REAL,
            position_size REAL,
            risk_ratio REAL,
            fund_flow TEXT,
            signals TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
        ''')
        
        # 历史K线数据表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS kline_data (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT NOT NULL,
            duration TEXT NOT NULL,
            datetime TEXT NOT NULL,
            open REAL,
            high REAL,
            low REAL,
            close REAL,
            volume INTEGER,
            open_interest INTEGER,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP,
            UNIQUE(symbol, duration, datetime)
        )
        ''')
        
        # 交易建议表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS trade_recommendations (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT NOT NULL,
            timestamp TEXT NOT NULL,
            direction TEXT,
            entry_price REAL,
            stop_loss REAL,
            target_price REAL,
            position_size REAL,
            execution_plan TEXT,
            risk_tips TEXT,
            status TEXT DEFAULT 'pending',
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
        ''')
        
        # 风险监控表
        cursor.execute('''
        CREATE TABLE IF NOT EXISTS risk_monitoring (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            symbol TEXT NOT NULL,
            timestamp TEXT NOT NULL,
            current_price REAL,
            entry_price REAL,
            stop_loss REAL,
            target_price REAL,
            current_profit REAL,
            risk_status TEXT,
            created_at TEXT DEFAULT CURRENT_TIMESTAMP
        )
        ''')
        
        conn.commit()
        conn.close()
    
    def save_analysis_result(self, result: Dict) -> bool:
        """保存分析结果"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 准备数据
            data = {
                'symbol': result.get('symbol', ''),
                'timestamp': result.get('timestamp', datetime.now().isoformat()),
                'trend': result.get('trend'),
                'probability': result.get('probability'),
                'direction': result.get('direction'),
                'cycle': result.get('cycle'),
                'atr': result.get('atr'),
                'adx': result.get('adx'),
                'support': result.get('support'),
                'resistance': result.get('resistance'),
                'stop_loss': result.get('stop_loss'),
                'target_price': result.get('target_price'),
                'position_size': result.get('position_size'),
                'risk_ratio': result.get('risk_ratio'),
                'fund_flow': json.dumps(result.get('fund_flow', {})) if result.get('fund_flow') else None,
                'signals': json.dumps(result.get('signals', {})) if result.get('signals') else None
            }
            
            # 插入数据
            cursor.execute('''
            INSERT INTO analysis_results (
                symbol, timestamp, trend, probability, direction, cycle, 
                atr, adx, support, resistance, stop_loss, target_price, 
                position_size, risk_ratio, fund_flow, signals
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                data['symbol'], data['timestamp'], data['trend'], data['probability'],
                data['direction'], data['cycle'], data['atr'], data['adx'],
                data['support'], data['resistance'], data['stop_loss'], data['target_price'],
                data['position_size'], data['risk_ratio'], data['fund_flow'], data['signals']
            ))
            
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"保存分析结果失败：{e}")
            return False
    
    def save_kline_data(self, symbol: str, duration: str, df: pd.DataFrame) -> bool:
        """保存K线数据"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 批量插入数据
            data_to_insert = []
            for idx, row in df.iterrows():
                data_to_insert.append((
                    symbol, duration, idx.isoformat(),
                    row['open'], row['high'], row['low'], row['close'],
                    row['volume'], row['open_interest']
                ))
            
            # 使用事务批量插入
            if data_to_insert:
                cursor.executemany('''
                INSERT OR IGNORE INTO kline_data (
                    symbol, duration, datetime, open, high, low, close, volume, open_interest
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                ''', data_to_insert)
                
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"保存K线数据失败：{e}")
            return False
    
    def save_trade_recommendation(self, recommendation: Dict) -> bool:
        """保存交易建议"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 准备数据
            data = {
                'symbol': recommendation.get('symbol', ''),
                'timestamp': recommendation.get('timestamp', datetime.now().isoformat()),
                'direction': recommendation.get('direction'),
                'entry_price': recommendation.get('entry_price'),
                'stop_loss': recommendation.get('stop_loss'),
                'target_price': recommendation.get('target_price'),
                'position_size': recommendation.get('position_size'),
                'execution_plan': recommendation.get('execution_plan'),
                'risk_tips': recommendation.get('risk_tips')
            }
            
            # 插入数据
            cursor.execute('''
            INSERT INTO trade_recommendations (
                symbol, timestamp, direction, entry_price, stop_loss, 
                target_price, position_size, execution_plan, risk_tips
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                data['symbol'], data['timestamp'], data['direction'], data['entry_price'],
                data['stop_loss'], data['target_price'], data['position_size'],
                data['execution_plan'], data['risk_tips']
            ))
            
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"保存交易建议失败：{e}")
            return False
    
    def save_risk_monitoring(self, monitoring_data: Dict) -> bool:
        """保存风险监控数据"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 准备数据
            data = {
                'symbol': monitoring_data.get('symbol', ''),
                'timestamp': monitoring_data.get('timestamp', datetime.now().isoformat()),
                'current_price': monitoring_data.get('current_price'),
                'entry_price': monitoring_data.get('entry_price'),
                'stop_loss': monitoring_data.get('stop_loss'),
                'target_price': monitoring_data.get('target_price'),
                'current_profit': monitoring_data.get('current_profit'),
                'risk_status': monitoring_data.get('risk_status')
            }
            
            # 插入数据
            cursor.execute('''
            INSERT INTO risk_monitoring (
                symbol, timestamp, current_price, entry_price, stop_loss, 
                target_price, current_profit, risk_status
            ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
            ''', (
                data['symbol'], data['timestamp'], data['current_price'], data['entry_price'],
                data['stop_loss'], data['target_price'], data['current_profit'], data['risk_status']
            ))
            
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"保存风险监控数据失败：{e}")
            return False
    
    def get_analysis_results(self, symbol: str, limit: int = 100) -> pd.DataFrame:
        """获取分析结果"""
        try:
            conn = sqlite3.connect(self.db_path)
            query = f"""
            SELECT * FROM analysis_results 
            WHERE symbol = ? 
            ORDER BY timestamp DESC 
            LIMIT ?
            """
            df = pd.read_sql_query(query, conn, params=(symbol, limit))
            conn.close()
            
            # 解析JSON字段
            if not df.empty:
                df['fund_flow'] = df['fund_flow'].apply(lambda x: json.loads(x) if x else {})
                df['signals'] = df['signals'].apply(lambda x: json.loads(x) if x else {})
            
            return df
        except Exception as e:
            print(f"获取分析结果失败：{e}")
            return pd.DataFrame()
    
    def get_kline_data(self, symbol: str, duration: str, limit: int = 200) -> pd.DataFrame:
        """获取K线数据"""
        try:
            conn = sqlite3.connect(self.db_path)
            query = f"""
            SELECT * FROM kline_data 
            WHERE symbol = ? AND duration = ? 
            ORDER BY datetime DESC 
            LIMIT ?
            """
            df = pd.read_sql_query(query, conn, params=(symbol, duration, limit))
            conn.close()
            
            if not df.empty:
                # 转换时间格式并设置索引
                df['datetime'] = pd.to_datetime(df['datetime'])
                df = df.sort_values('datetime')
                df.set_index('datetime', inplace=True)
                # 选择需要的列
                df = df[['open', 'high', 'low', 'close', 'volume', 'open_interest']]
            
            return df
        except Exception as e:
            print(f"获取K线数据失败：{e}")
            return pd.DataFrame()
    
    def get_trade_recommendations(self, symbol: str, status: Optional[str] = None) -> pd.DataFrame:
        """获取交易建议"""
        try:
            conn = sqlite3.connect(self.db_path)
            if status:
                query = f"""
                SELECT * FROM trade_recommendations 
                WHERE symbol = ? AND status = ? 
                ORDER BY timestamp DESC
                """
                df = pd.read_sql_query(query, conn, params=(symbol, status))
            else:
                query = f"""
                SELECT * FROM trade_recommendations 
                WHERE symbol = ? 
                ORDER BY timestamp DESC
                """
                df = pd.read_sql_query(query, conn, params=(symbol,))
            conn.close()
            return df
        except Exception as e:
            print(f"获取交易建议失败：{e}")
            return pd.DataFrame()
    
    def update_recommendation_status(self, recommendation_id: int, status: str) -> bool:
        """更新交易建议状态"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            cursor.execute('''
            UPDATE trade_recommendations 
            SET status = ? 
            WHERE id = ?
            ''', (status, recommendation_id))
            
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"更新交易建议状态失败：{e}")
            return False
    
    def delete_old_data(self, days: int = 30) -> bool:
        """删除旧数据"""
        try:
            conn = sqlite3.connect(self.db_path)
            cursor = conn.cursor()
            
            # 计算删除时间点
            delete_time = (datetime.now() - pd.Timedelta(days=days)).isoformat()
            
            # 删除旧的分析结果
            cursor.execute('DELETE FROM analysis_results WHERE created_at < ?', (delete_time,))
            
            # 删除旧的K线数据
            cursor.execute('DELETE FROM kline_data WHERE created_at < ?', (delete_time,))
            
            # 删除旧的交易建议
            cursor.execute('DELETE FROM trade_recommendations WHERE created_at < ?', (delete_time,))
            
            # 删除旧的风险监控数据
            cursor.execute('DELETE FROM risk_monitoring WHERE created_at < ?', (delete_time,))
            
            conn.commit()
            conn.close()
            return True
        except Exception as e:
            print(f"删除旧数据失败：{e}")
            return False
