"""
智能盯盘 - DeepSeek AI 决策引擎
适配A股T+1交易规则的AI决策系统
"""

import logging
from typing import Dict, List, Optional
from datetime import datetime, time
import pytz


class SmartMonitorDeepSeek:
    """A股智能盯盘 - DeepSeek AI决策引擎"""

    def __init__(self, api_key: str):
        """
        初始化DeepSeek客户端
        
        Args:
            api_key: DeepSeek API密钥
        """
        self.api_key = api_key
        self.base_url = "https://api.deepseek.com/v1"
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        self.logger = logging.getLogger(__name__)

    def is_trading_time(self) -> bool:
        """
        判断当前是否在A股交易时间内
        
        Returns:
            bool: 是否可以交易
        """
        beijing_tz = pytz.timezone('Asia/Shanghai')
        now = datetime.now(beijing_tz)
        current_time = now.time()
        
        # 排除周末
        if now.weekday() >= 5:
            return False
        
        # 上午：9:30-11:30
        morning_start = time(9, 30)
        morning_end = time(11, 30)
        
        # 下午：13:00-15:00
        afternoon_start = time(13, 0)
        afternoon_end = time(15, 0)
        
        is_trading = (
            (morning_start <= current_time <= morning_end) or
            (afternoon_start <= current_time <= afternoon_end)
        )
        
        return is_trading

    def get_trading_session(self) -> Dict:
        """
        获取当前交易时段信息（A股版本）
        
        Returns:
            Dict: 时段信息
        """
        beijing_tz = pytz.timezone('Asia/Shanghai')
        now = datetime.now(beijing_tz)
        current_time = now.time()
        
        # 判断是否交易日
        if now.weekday() >= 5:
            return {
                'session': '休市',
                'volatility': 'none',
                'recommendation': '周末不可交易',
                'beijing_hour': now.hour,
                'can_trade': False
            }
        
        # 开盘前（9:00-9:30）：集合竞价时段
        if time(9, 0) <= current_time < time(9, 30):
            return {
                'session': '集合竞价',
                'volatility': 'high',
                'recommendation': '可观察盘面情绪，准备开盘交易',
                'beijing_hour': now.hour,
                'can_trade': False
            }
        
        # 上午盘（9:30-11:30）
        elif time(9, 30) <= current_time <= time(11, 30):
            return {
                'session': '上午盘',
                'volatility': 'high',
                'recommendation': '交易活跃，波动较大',
                'beijing_hour': now.hour,
                'can_trade': True
            }
        
        # 午间休市（11:30-13:00）
        elif time(11, 30) < current_time < time(13, 0):
            return {
                'session': '午间休市',
                'volatility': 'none',
                'recommendation': '不可交易，可分析上午盘面',
                'beijing_hour': now.hour,
                'can_trade': False
            }
        
        # 下午盘（13:00-15:00）
        elif time(13, 0) <= current_time <= time(15, 0):
            # 尾盘最后半小时（14:30-15:00）
            if current_time >= time(14, 30):
                return {
                    'session': '尾盘',
                    'volatility': 'high',
                    'recommendation': '尾盘波动大，谨慎操作',
                    'beijing_hour': now.hour,
                    'can_trade': True
                }
            else:
                return {
                    'session': '下午盘',
                    'volatility': 'medium',
                    'recommendation': '波动趋缓，适合布局',
                    'beijing_hour': now.hour,
                    'can_trade': True
                }
        
        # 盘后（15:00之后）
        else:
            return {
                'session': '盘后',
                'volatility': 'none',
                'recommendation': '收盘后，可复盘分析',
                'beijing_hour': now.hour,
                'can_trade': False
            }

    def chat_completion(self, messages: List[Dict], model: str = "deepseek-chat",
                       temperature: float = 0.7, max_tokens: int = 2000) -> Dict:
        """
        调用DeepSeek API
        
        Args:
            messages: 对话消息列表
            model: 模型名称
            temperature: 温度参数
            max_tokens: 最大token数
            
        Returns:
            API响应
        """
        import requests
        
        payload = {
            "model": model,
            "messages": messages,
            "temperature": temperature,
            "max_tokens": max_tokens
        }
        
        try:
            response = requests.post(
                f"{self.base_url}/chat/completions",
                headers=self.headers,
                json=payload,
                timeout=60
            )
            response.raise_for_status()
            return response.json()
        except Exception as e:
            self.logger.error(f"DeepSeek API调用失败: {e}")
            raise

    def analyze_stock_and_decide(self, stock_code: str, market_data: Dict,
                                 account_info: Dict, has_position: bool = False,
                                 position_cost: float = 0, position_quantity: int = 0) -> Dict:
        """
        分析股票并做出交易决策（A股T+1规则）
        
        Args:
            stock_code: 股票代码（如：600519）
            market_data: 市场数据
            account_info: 账户信息
            has_position: 是否已持有该股票
            position_cost: 持仓成本价格
            position_quantity: 持仓数量
            
        Returns:
            交易决策
        """
        # 获取交易时段
        session_info = self.get_trading_session()
        
        # 构建Prompt
        prompt = self._build_a_stock_prompt(
            stock_code, market_data, account_info, 
            has_position, session_info, position_cost, position_quantity
        )
        
        system_prompt = """你是一位资深的A股量化交易专家，拥有15年实战经验。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
⚠️ A股交易规则（与币圈完全不同！）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[CRITICAL] T+1规则：
- 今天买入的股票，**今天不能卖出**，必须等到下一个交易日
- 这意味着：一旦买入，至少要持有到明天才能卖出
- 因此买入决策必须**极其谨慎**，不能像币圈那样快进快出

[CRITICAL] 涨跌停限制：
- 主板/中小板：±10%涨跌停
- 创业板/科创板：±20%涨跌停
- ST股票：±5%涨跌停
- 一旦涨停，很难买入；一旦跌停，很难卖出

[CRITICAL] 交易时间：
- 上午：9:30-11:30
- 下午：13:00-15:00
- 其他时间不能交易

[CRITICAL] 只能做多：
- A股不能做空（融券门槛高，散户基本不用）
- 只有买入和卖出两个动作

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎯 你的交易哲学（适配T+1）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

**因为T+1限制，你的策略必须更加稳健！**

1. **买入前三思**：
   - 买入后至少持有1天，所以必须确保趋势向上
   - 不能像币圈那样"试探性开仓"，一旦买入就是承诺
   - 最好在尾盘或第二天开盘前决策，避免盲目追高

2. **止损更困难**：
   - 如果今天买入后下跌，今天无法止损（T+1）
   - 只能等明天再卖，可能面临更大亏损
   - 因此：**宁可错过，不可做错**

3. **技术分析更重要**：
   - 日线级别趋势确认
   - 支撑位/阻力位
   - 成交量配合
   - 量价关系判断

4. **风险控制严格**：
   - 单只股票仓位 ≤ 30%（T+1风险大）
   - 止损位：-5%（明天开盘立即执行）
   - 止盈位：+8-15%（分批止盈）

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📊 可选的交易动作
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

**如果当前无持仓**：
- action = "BUY"（买入）- 必须确保技术面强势，趋势向上
- action = "HOLD"（观望）- 信号不明确时选择观望

**如果当前有持仓**：
- action = "SELL"（卖出）- 达到止盈/止损条件，或技术面转弱
- action = "HOLD"（持有）- 趋势未改变，继续持有
- ⚠️ 注意：如果股票是今天买入的，受T+1限制无法卖出，只能选择HOLD

**绝对禁止**：
- 不要在开盘前5分钟（9:30-9:35）买入，容易追高
- 不要在尾盘最后5分钟（14:55-15:00）买入，可能被套
- 不要逆趋势交易（趋势向下时买入）

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📈 买入信号（必须满足至少3个条件）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. ✅ 趋势向上：价格 > MA5 > MA20 > MA60（多头排列）
2. ✅ 量价配合：成交量 > 5日均量的120%（放量上涨）
3. ✅ MACD金叉：MACD > 0 且DIF上穿DEA
4. ✅ RSI健康：RSI在50-70区间（不超买不超卖）
5. ✅ 突破关键位：突破前期高点或重要阻力位
6. ✅ 布林带位置：价格接近布林中轨上方，有上行空间

**加分项**：
- 行业板块同步上涨
- 有重大利好消息
- 机构调研增加

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📉 卖出信号（满足任一条件立即卖出）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

1. 🔴 止损触发：亏损 ≥ -5%（明天开盘立即卖出）
2. 🟢 止盈触发：盈利 ≥ +10%（分批止盈，先卖一半）
3. 🔴 趋势转弱：跌破MA20或MA60，且MACD死叉
4. 🔴 放量下跌：成交量放大但价格下跌（主力出货）
5. 🔴 技术破位：跌破重要支撑位
6. 🔴 重大利空：公司公告重大利空消息

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💬 返回格式（必须严格JSON）
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

{
    "action": "BUY" | "SELL" | "HOLD",
    "confidence": 0-100,
    "reasoning": "详细的决策理由，包括技术分析、风险评估等，200-300字",
    "position_size_pct": 10-30,  // 建议仓位百分比（因为T+1，建议≤30%）
    "stop_loss_pct": 5.0,  // 止损百分比（建议5%）
    "take_profit_pct": 10.0,  // 止盈百分比（建议10-15%）
    "risk_level": "low" | "medium" | "high",
    "key_price_levels": {
        "support": 支撑位价格,
        "resistance": 阻力位价格,
        "stop_loss": 止损位价格
    }
}

**reasoning 示例**：
"茅台当前价格1650元，日线级别呈多头排列（MA5 1645 > MA20 1620 > MA60 1580），
MACD金叉且柱状图持续放大，RSI 62处于健康区间。今日成交量较5日均量放大135%，
显示有增量资金入场。技术面支撑位在1630元附近，阻力位在1680元。综合判断短期
趋势向上，但考虑T+1规则，建议仓位控制在20%，止损位设在1568元（-5%），
止盈目标1815元（+10%）。风险提示：如明日低开需谨慎..."
"""

        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": prompt}
        ]

        try:
            response = self.chat_completion(messages, temperature=0.3)
            ai_response = response['choices'][0]['message']['content']
            
            # 解析JSON决策
            decision = self._parse_decision(ai_response)
            
            return {
                'success': True,
                'decision': decision,
                'raw_response': ai_response
            }
            
        except Exception as e:
            self.logger.error(f"AI决策失败: {e}")
            return {
                'success': False,
                'error': str(e)
            }

    def _build_a_stock_prompt(self, stock_code: str, market_data: Dict,
                             account_info: Dict, has_position: bool,
                             session_info: Dict, position_cost: float = 0, 
                             position_quantity: int = 0) -> str:
        """构建A股分析提示词"""
        
        prompt = f"""
[TIMER] 当前交易时段
═══════════════════════════════════════════════════════════
当前时段: {session_info['session']} (北京时间{session_info['beijing_hour']}:00)
市场状态: {session_info['volatility'].upper()}
时段建议: {session_info['recommendation']}
可交易: {'是' if session_info['can_trade'] else '否'}

[STOCK] 股票基本信息
═══════════════════════════════════════════════════════════
股票代码: {stock_code}
股票名称: {market_data.get('name', 'N/A')}
当前价格: ¥{market_data.get('current_price', 0):.2f}
今日涨跌: {market_data.get('change_pct', 0):+.2f}%
今日涨跌额: ¥{market_data.get('change_amount', 0):+.2f}
最高价: ¥{market_data.get('high', 0):.2f}
最低价: ¥{market_data.get('low', 0):.2f}
开盘价: ¥{market_data.get('open', 0):.2f}
昨收价: ¥{market_data.get('pre_close', 0):.2f}
成交量: {market_data.get('volume', 0):,.0f}手
成交额: ¥{market_data.get('amount', 0):,.2f}万

[TECHNICAL] 技术指标
═══════════════════════════════════════════════════════════
MA5: ¥{market_data.get('ma5', 0):.2f}
MA20: ¥{market_data.get('ma20', 0):.2f}
MA60: ¥{market_data.get('ma60', 0):.2f}
趋势判断: {'多头排列' if market_data.get('trend') == 'up' else '空头排列' if market_data.get('trend') == 'down' else '震荡'}

MACD:
  DIF: {market_data.get('macd_dif', 0):.4f}
  DEA: {market_data.get('macd_dea', 0):.4f}
  MACD: {market_data.get('macd', 0):.4f} ({'金叉' if market_data.get('macd', 0) > 0 else '死叉'})

RSI(6): {market_data.get('rsi6', 50):.2f} {'[超买]' if market_data.get('rsi6', 50) > 80 else '[超卖]' if market_data.get('rsi6', 50) < 20 else '[正常]'}
RSI(12): {market_data.get('rsi12', 50):.2f}
RSI(24): {market_data.get('rsi24', 50):.2f}

KDJ:
  K: {market_data.get('kdj_k', 50):.2f}
  D: {market_data.get('kdj_d', 50):.2f}
  J: {market_data.get('kdj_j', 50):.2f}

布林带:
  上轨: ¥{market_data.get('boll_upper', 0):.2f}
  中轨: ¥{market_data.get('boll_mid', 0):.2f}
  下轨: ¥{market_data.get('boll_lower', 0):.2f}
  位置: {market_data.get('boll_position', 'N/A')}

[VOLUME] 量能分析
═══════════════════════════════════════════════════════════
今日成交量: {market_data.get('volume', 0):,.0f}手
5日均量: {market_data.get('vol_ma5', 0):,.0f}手
量比: {market_data.get('volume_ratio', 0):.2f} ({'放量' if market_data.get('volume_ratio', 0) > 1.2 else '缩量' if market_data.get('volume_ratio', 0) < 0.8 else '正常'})
换手率: {market_data.get('turnover_rate', 0):.2f}%

[ACCOUNT] 账户状态
═══════════════════════════════════════════════════════════
可用资金: ¥{account_info.get('available_cash', 0):,.2f}
总资产: ¥{account_info.get('total_value', 0):,.2f}
持仓数量: {account_info.get('positions_count', 0)}
"""

        # 如果已持有该股票
        if has_position and position_cost > 0 and position_quantity > 0:
            current_price = market_data.get('current_price', 0)
            cost_total = position_cost * position_quantity
            current_total = current_price * position_quantity
            profit_loss = current_total - cost_total
            profit_loss_pct = (profit_loss / cost_total * 100) if cost_total > 0 else 0
            
            prompt += f"""
[POSITION] 当前持仓（{stock_code}） ⭐ 重要
═══════════════════════════════════════════════════════════
持仓数量: {position_quantity}股
成本价: ¥{position_cost:.2f}
当前价: ¥{current_price:.2f}
持仓市值: ¥{current_total:,.2f}
浮动盈亏: ¥{profit_loss:,.2f} ({profit_loss_pct:+.2f}%)

⚠️ T+1限制: 该股票可以卖出（不受T+1限制）

💡 决策建议：
- 如果盈利且技术指标转弱 → 建议止盈卖出
- 如果亏损超过止损线（通常-5%）→ 建议止损卖出
- 如果技术指标强势且未到止盈位 → 建议继续持有
- 如果盈利且看好后市 → 可考虑加仓（但注意仓位控制）
"""
        else:
            prompt += """
[POSITION] 当前无持仓
═══════════════════════════════════════════════════════════
可考虑买入，但必须确保：
1. 技术面强势（满足至少3个买入信号）
2. 有足够的安全边际
3. 考虑T+1规则，买入后至少持有1天
4. 控制仓位，建议单只股票仓位≤30%
"""

        # 主力资金数据（已禁用 - 接口不稳定）
        # if 'main_force' in market_data:
        #     mf = market_data['main_force']
        #     prompt += f"""
        # [MONEY] 主力资金流向
        # ═══════════════════════════════════════════════════════════
        # 主力净额: ¥{mf.get('main_net', 0):,.2f}万 ({mf.get('main_net_pct', 0):+.2f}%)
        # 超大单: ¥{mf.get('super_net', 0):,.2f}万
        # 大单: ¥{mf.get('big_net', 0):,.2f}万
        # 中单: ¥{mf.get('mid_net', 0):,.2f}万
        # 小单: ¥{mf.get('small_net', 0):,.2f}万
        # 主力动向: {mf.get('trend', '观望')}
        # """

        prompt += "\n请基于以上数据，给出交易决策（JSON格式）。"
        
        return prompt

    def _parse_decision(self, ai_response: str) -> Dict:
        """解析AI决策响应"""
        import json
        
        try:
            # 尝试多种提取方式
            if "```json" in ai_response.lower():
                json_start = ai_response.lower().find("```json") + 7
                json_end = ai_response.find("```", json_start)
                json_str = ai_response[json_start:json_end].strip()
            elif "```" in ai_response:
                first_tick = ai_response.find("```")
                json_start = ai_response.find("\n", first_tick) + 1
                json_end = ai_response.find("```", json_start)
                json_str = ai_response[json_start:json_end].strip()
            elif "{" in ai_response and "}" in ai_response:
                start_idx = ai_response.find('{')
                end_idx = ai_response.rfind('}') + 1
                json_str = ai_response[start_idx:end_idx]
            else:
                json_str = ai_response
            
            decision = json.loads(json_str)
            
            # 验证必需字段
            required_fields = ['action', 'confidence', 'reasoning']
            for field in required_fields:
                if field not in decision:
                    raise ValueError(f"缺少必需字段: {field}")
            
            # 设置默认值
            decision.setdefault('position_size_pct', 20)
            decision.setdefault('stop_loss_pct', 5.0)
            decision.setdefault('take_profit_pct', 10.0)
            decision.setdefault('risk_level', 'medium')
            
            return decision
            
        except Exception as e:
            self.logger.error(f"解析AI决策失败: {e}")
            # 返回保守决策
            return {
                'action': 'HOLD',
                'confidence': 0,
                'reasoning': f'AI响应解析失败: {str(e)}',
                'position_size_pct': 0,
                'stop_loss_pct': 5.0,
                'take_profit_pct': 10.0,
                'risk_level': 'high'
            }

