"""
个股标签关联分析器
使用联网大模型分析个股与标签的关联性，并输出结构化结果
"""

import logging
import json
import re
from typing import Dict, Any, Optional, List
from datetime import datetime

# 导入联网大模型工具
import sys
import os

try:
    from .chat_bot import ChatBot
except ImportError:
    try:
        from src.stock_tag_analysis.chat_bot import ChatBot
    except ImportError:
        # 如果相对导入失败，添加路径并使用绝对导入
        current_dir = os.path.dirname(os.path.abspath(__file__))
        sys.path.insert(0, current_dir)
        from chat_bot import ChatBot

# 设置日志记录
logger = logging.getLogger(__name__)


class TagRelationAnalyzer:
    """个股标签关联分析器"""
    
    def __init__(self, model_type: str = "ds3_2", enable_web_search: bool = True):
        """初始化分析器
        
        Args:
            model_type: 大模型类型，默认为 ds3_2（联网智能体）
            enable_web_search: 是否启用联网搜索，默认True
        """
        self.chat_bot = ChatBot(model_type=model_type, enable_web_search=enable_web_search)
        logger.info(f"TagRelationAnalyzer 初始化完成，模型: {model_type}, 联网搜索: {enable_web_search}")
    
    def _build_analysis_prompt(self, stock_code: str, stock_name: str, tag_name: str) -> str:
        """构建分析提示词
        
        Args:
            stock_code: 股票代码
            stock_name: 股票名称
            tag_name: 标签名称
            
        Returns:
            str: 分析提示词
        """
        prompt = f"""请分析股票"{stock_name}"（股票代码：{stock_code}）与标签"{tag_name}"是否存在关联性。

请通过联网搜索获取最新的信息，包括但不限于：
1. 公司主营业务是否与标签相关
2. 公司产品、服务是否涉及标签领域
3. 公司是否在标签相关行业有布局
4. 公司公告、新闻中是否提及标签相关内容
5. 公司财务数据是否显示与标签相关的业务占比

请按照以下JSON格式输出分析结果：
{{
    "has_relation": true/false,  // 是否存在关联性
    "relation_score": 0-100,     // 关联度评分（0-100，数值越高关联度越高）
    "relation_type": "直接关联/间接关联/无关联",  // 关联类型
    "analysis_summary": "简要分析总结（100字以内）",
    "detailed_analysis": "详细分析内容（包括关联依据、业务占比、市场表现等）",
    "key_evidence": [  // 关键证据列表
        {{
            "evidence_type": "主营业务/产品服务/行业布局/公告新闻/财务数据",
            "description": "证据描述",
            "relevance": "高/中/低"
        }}
    ],
    "business_ratio": "与标签相关的业务占比（如：30%、主要业务、次要业务等，如无相关信息则填写'未知'）",
    "market_performance": "市场表现相关描述（如：该标签概念股表现、行业地位等，如无相关信息则填写'未知'）",
    "conclusion": "最终结论（50字以内）"
}}

请确保输出的是有效的JSON格式，不要包含任何其他文字说明。"""
        return prompt
    
    def _parse_json_response(self, response_text: str) -> Optional[Dict[str, Any]]:
        """从响应文本中解析JSON
        
        Args:
            response_text: 响应文本
            
        Returns:
            Optional[Dict[str, Any]]: 解析后的JSON字典，如果解析失败返回None
        """
        try:
            # 尝试直接解析JSON
            # 查找JSON代码块
            json_match = re.search(r'```json\s*(\{.*?\})\s*```', response_text, re.DOTALL)
            if json_match:
                json_str = json_match.group(1)
            else:
                # 查找大括号包裹的JSON
                json_match = re.search(r'\{.*\}', response_text, re.DOTALL)
                if json_match:
                    json_str = json_match.group(0)
                else:
                    # 尝试直接解析整个响应
                    json_str = response_text.strip()
            
            # 清理可能的Markdown标记
            json_str = json_str.strip()
            if json_str.startswith('```'):
                json_str = re.sub(r'^```[a-z]*\n?', '', json_str)
            if json_str.endswith('```'):
                json_str = re.sub(r'\n?```$', '', json_str)
            
            # 解析JSON
            result = json.loads(json_str)
            return result
        except json.JSONDecodeError as e:
            logger.error(f"JSON解析失败: {str(e)}")
            logger.error(f"响应文本: {response_text[:500]}")
            return None
        except Exception as e:
            logger.error(f"解析响应时出错: {str(e)}")
            return None
    
    def analyze_tag_relation(
        self,
        stock_code: str,
        stock_name: str,
        tag_name: str,
        temperature: float = 0.7,
        max_tokens: int = 4096
    ) -> Dict[str, Any]:
        """分析个股与标签的关联性
        
        Args:
            stock_code: 股票代码（如：300750.SZ）
            stock_name: 股票名称（如：宁德时代）
            tag_name: 标签名称（如：医药、新能源、金融科技等）
            temperature: 大模型温度参数，默认0.7
            max_tokens: 最大token数，默认4096
            
        Returns:
            Dict[str, Any]: 分析结果，包含以下字段：
                - success: 是否成功
                - stock_code: 股票代码
                - stock_name: 股票名称
                - tag_name: 标签名称
                - has_relation: 是否存在关联性
                - relation_score: 关联度评分（0-100）
                - relation_type: 关联类型
                - analysis_summary: 简要分析总结
                - detailed_analysis: 详细分析内容
                - key_evidence: 关键证据列表
                - business_ratio: 业务占比
                - market_performance: 市场表现
                - conclusion: 最终结论
                - raw_response: 原始响应
                - reasoning_process: 推理过程
                - references: 参考资料
                - analysis_time: 分析时间
                - error: 错误信息（如果失败）
        """
        try:
            logger.info(f"开始分析 {stock_name}({stock_code}) 与标签 {tag_name} 的关联性")
            
            # 构建分析提示词
            prompt = self._build_analysis_prompt(stock_code, stock_name, tag_name)
            
            # 调用大模型进行分析
            result = self.chat_bot.chat(
                user_input=prompt,
                temperature=temperature,
                max_tokens=max_tokens
            )
            
            # 解析响应
            response_text = result.get("response", "")
            reasoning_process = result.get("reasoning_process", "")
            references = result.get("references", [])
            
            # 解析JSON结果
            parsed_result = self._parse_json_response(response_text)
            
            if parsed_result is None:
                # 如果解析失败，返回原始响应
                logger.warning("JSON解析失败，返回原始响应")
                return {
                    "success": False,
                    "stock_code": stock_code,
                    "stock_name": stock_name,
                    "tag_name": tag_name,
                    "has_relation": None,
                    "relation_score": None,
                    "relation_type": None,
                    "analysis_summary": None,
                    "detailed_analysis": response_text,
                    "key_evidence": [],
                    "business_ratio": None,
                    "market_performance": None,
                    "conclusion": None,
                    "raw_response": response_text,
                    "reasoning_process": reasoning_process,
                    "references": references,
                    "analysis_time": datetime.now().isoformat(),
                    "error": "JSON解析失败，请检查响应格式"
                }
            
            # 构建完整结果
            analysis_result = {
                "success": True,
                "stock_code": stock_code,
                "stock_name": stock_name,
                "tag_name": tag_name,
                "has_relation": parsed_result.get("has_relation", False),
                "relation_score": parsed_result.get("relation_score", 0),
                "relation_type": parsed_result.get("relation_type", "无关联"),
                "analysis_summary": parsed_result.get("analysis_summary", ""),
                "detailed_analysis": parsed_result.get("detailed_analysis", ""),
                "key_evidence": parsed_result.get("key_evidence", []),
                "business_ratio": parsed_result.get("business_ratio", "未知"),
                "market_performance": parsed_result.get("market_performance", "未知"),
                "conclusion": parsed_result.get("conclusion", ""),
                "raw_response": response_text,
                "reasoning_process": reasoning_process,
                "references": references,
                "analysis_time": datetime.now().isoformat(),
                "error": None
            }
            
            logger.info(f"分析完成: {stock_name}({stock_code}) 与 {tag_name} 的关联度评分为 {analysis_result['relation_score']}")
            
            return analysis_result
            
        except Exception as e:
            logger.error(f"分析过程中出错: {str(e)}", exc_info=True)
            return {
                "success": False,
                "stock_code": stock_code,
                "stock_name": stock_name,
                "tag_name": tag_name,
                "has_relation": None,
                "relation_score": None,
                "relation_type": None,
                "analysis_summary": None,
                "detailed_analysis": None,
                "key_evidence": [],
                "business_ratio": None,
                "market_performance": None,
                "conclusion": None,
                "raw_response": None,
                "reasoning_process": None,
                "references": [],
                "analysis_time": datetime.now().isoformat(),
                "error": str(e)
            }
    
    def batch_analyze_tag_relation(
        self,
        stock_list: List[Dict[str, str]],
        tag_name: str,
        temperature: float = 0.7,
        max_tokens: int = 4096
    ) -> List[Dict[str, Any]]:
        """批量分析多只股票与标签的关联性
        
        Args:
            stock_list: 股票列表，每个元素包含 stock_code 和 stock_name
            tag_name: 标签名称
            temperature: 大模型温度参数
            max_tokens: 最大token数
            
        Returns:
            List[Dict[str, Any]]: 分析结果列表
        """
        results = []
        for stock in stock_list:
            stock_code = stock.get("stock_code")
            stock_name = stock.get("stock_name")
            
            if not stock_code or not stock_name:
                logger.warning(f"跳过无效股票信息: {stock}")
                continue
            
            result = self.analyze_tag_relation(
                stock_code=stock_code,
                stock_name=stock_name,
                tag_name=tag_name,
                temperature=temperature,
                max_tokens=max_tokens
            )
            results.append(result)
            
            # 清除对话历史，避免上下文干扰
            self.chat_bot.clear_history()
        
        return results


if __name__ == "__main__":
    # 设置日志
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # 测试示例
    analyzer = TagRelationAnalyzer()
    
    # 测试：分析宁德时代与医药标签的关联性
    result = analyzer.analyze_tag_relation(
        stock_code="300750.SZ",
        stock_name="宁德时代",
        tag_name="医药"
    )
    
    print("\n" + "="*50)
    print("分析结果：")
    print("="*50)
    print(json.dumps(result, ensure_ascii=False, indent=2))

