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

from ..core.database import db_manager
from ..core.models import WorkOrder, Conversation
from ..core.llm_client import QwenClient
from ..knowledge_base.knowledge_manager import KnowledgeManager
from ..vehicle.vehicle_data_manager import VehicleDataManager
from .conversation_history import ConversationHistoryManager
from ..analytics.token_monitor import TokenMonitor
from ..analytics.ai_success_monitor import AISuccessMonitor
from ..core.system_optimizer import SystemOptimizer

logger = logging.getLogger(__name__)

class DialogueManager:
    """对话管理器"""
    
    def __init__(self):
        self.llm_client = QwenClient()
        self.knowledge_manager = KnowledgeManager()
        self.vehicle_manager = VehicleDataManager()
        self.history_manager = ConversationHistoryManager()
        self.token_monitor = TokenMonitor()
        self.ai_success_monitor = AISuccessMonitor()
        self.system_optimizer = SystemOptimizer()
        self.conversation_history = {}  # 存储对话历史
    
    def process_user_message(
        self,
        user_message: str,
        work_order_id: Optional[int] = None,
        user_id: Optional[str] = None,
        vehicle_id: Optional[str] = None
    ) -> Dict[str, Any]:
        """处理用户消息"""
        start_time = datetime.now()
        success = False
        error_message = None
        
        try:
            # 检查频率限制
            if not self.system_optimizer.check_rate_limit(user_id or "anonymous"):
                return {"error": "请求频率过高，请稍后再试"}
            
            # 检查输入安全性
            security_check = self.system_optimizer.check_input_security(user_message)
            if not security_check["is_safe"]:
                return {"error": f"输入不安全: {security_check['message']}"}
            
            # 搜索相关知识库（只搜索已验证的）
            knowledge_results = self.knowledge_manager.search_knowledge(
                user_message, top_k=3, verified_only=True
            )
            
            # 获取车辆实时数据
            vehicle_data = None
            if vehicle_id:
                vehicle_data = self.vehicle_manager.get_latest_vehicle_data(vehicle_id)
            
            # 构建上下文（包含历史对话）
            context = self._build_context(work_order_id, user_id)
            
            # 准备知识库信息
            knowledge_context = ""
            if knowledge_results:
                knowledge_context = "相关知识库信息:\n"
                for i, result in enumerate(knowledge_results[:2], 1):
                    knowledge_context += f"{i}. 问题: {result['question']}\n"
                    knowledge_context += f"   答案: {result['answer']}\n"
                    knowledge_context += f"   置信度: {result['confidence_score']:.2f}\n\n"
            
            # 准备车辆数据信息
            vehicle_context = ""
            if vehicle_data:
                vehicle_context = "车辆实时数据:\n"
                for data_type, data_info in vehicle_data.items():
                    vehicle_context += f"- {data_type}: {json.dumps(data_info['value'], ensure_ascii=False)}\n"
                    vehicle_context += f"  更新时间: {data_info['timestamp']}\n"
                vehicle_context += "\n"
            
            # 生成回复
            response_result = self.llm_client.generate_response(
                user_message=user_message,
                context=context,
                knowledge_base=[knowledge_context] if knowledge_context else None,
                vehicle_data=[vehicle_context] if vehicle_context else None
            )
            
            if "error" in response_result:
                error_message = response_result["error"]
                success = False
            else:
                success = True
            
            # 计算响应时间
            response_time = (datetime.now() - start_time).total_seconds()
            
            # 性能优化分析
            optimization_result = self.system_optimizer.optimize_response_time(response_time)
            
            # 记录Token使用情况（兼容多种返回格式）
            if success:
                # 兼容返回 usage: {prompt_tokens, completion_tokens}
                usage = response_result.get("usage", {}) or {}
                token_usage = response_result.get("token_usage", {}) or {}
                input_tokens = token_usage.get("input_tokens")
                output_tokens = token_usage.get("output_tokens")
                if input_tokens is None and isinstance(usage, dict):
                    input_tokens = usage.get("prompt_tokens") or usage.get("input_tokens") or 0
                if output_tokens is None and isinstance(usage, dict):
                    output_tokens = usage.get("completion_tokens") or usage.get("output_tokens") or 0

                # 若均为0，使用简易估算（避免记录缺失）
                if not input_tokens and user_message:
                    try:
                        input_tokens = max(1, len(user_message) // 4)
                    except Exception:
                        input_tokens = 0
                if not output_tokens and response_result.get("response"):
                    try:
                        output_tokens = max(1, len(response_result.get("response")) // 4)
                    except Exception:
                        output_tokens = 0

                model_name = response_result.get("model") or response_result.get("model_name") or "qwen-plus-latest"

                # 计算成本并限制
                estimated_cost = self.token_monitor._calculate_cost(
                    model_name,
                    int(input_tokens or 0),
                    int(output_tokens or 0)
                )
                if not self.system_optimizer.check_cost_limit(estimated_cost):
                    return {"error": "请求成本超限，请稍后再试"}

                self.token_monitor.record_token_usage(
                    user_id=user_id or "anonymous",
                    work_order_id=work_order_id,
                    model_name=model_name,
                    input_tokens=int(input_tokens or 0),
                    output_tokens=int(output_tokens or 0),
                    response_time=response_time,
                    success=success,
                    error_message=error_message
                )
            
            # 记录API调用
            self.ai_success_monitor.record_api_call(
                user_id=user_id or "anonymous",
                work_order_id=work_order_id,
                model_name=response_result.get("model_name", "qwen-plus-latest"),
                endpoint="chat/completions",
                success=success,
                response_time=response_time,
                error_message=error_message,
                input_length=len(user_message),
                output_length=len(response_result.get("response", ""))
            )
            
            if not success:
                return response_result
            
            # 保存对话记录到历史管理器
            conversation_id = self.history_manager.save_conversation(
                user_id=user_id or "anonymous",
                work_order_id=work_order_id,
                user_message=user_message,
                assistant_response=response_result["response"],
                confidence_score=self._calculate_confidence(knowledge_results),
                response_time=response_time,
                knowledge_used=[r["id"] for r in knowledge_results]
            )
            
            # 更新内存中的对话历史
            if user_id:
                if user_id not in self.conversation_history:
                    self.conversation_history[user_id] = []
                self.conversation_history[user_id].append({
                    "role": "user",
                    "content": user_message,
                    "timestamp": datetime.now().isoformat()
                })
                self.conversation_history[user_id].append({
                    "role": "assistant",
                    "content": response_result["response"],
                    "timestamp": datetime.now().isoformat()
                })
                
                # 保持历史记录在限制范围内
                if len(self.conversation_history[user_id]) > 20:  # 10轮对话
                    self.conversation_history[user_id] = self.conversation_history[user_id][-20:]
            
            return {
                "response": response_result["response"],
                "conversation_id": conversation_id,
                "knowledge_used": knowledge_results,
                "confidence_score": self._calculate_confidence(knowledge_results),
                "response_time": response_time,
                "optimization": optimization_result,
                "timestamp": datetime.now().isoformat()
            }
            
        except Exception as e:
            error_message = str(e)
            response_time = (datetime.now() - start_time).total_seconds()
            
            # 记录失败的API调用
            self.ai_success_monitor.record_api_call(
                user_id=user_id or "anonymous",
                work_order_id=work_order_id,
                model_name="qwen-plus-latest",
                endpoint="chat/completions",
                success=False,
                response_time=response_time,
                error_message=error_message,
                input_length=len(user_message),
                output_length=0
            )
            
            logger.error(f"处理用户消息失败: {e}")
            return {"error": f"处理失败: {str(e)}"}
    
    def _build_context(self, work_order_id: Optional[int], user_id: Optional[str]) -> str:
        """构建对话上下文"""
        context_parts = []
        
        # 添加工单信息
        if work_order_id:
            try:
                with db_manager.get_session() as session:
                    work_order = session.query(WorkOrder).filter(
                        WorkOrder.id == work_order_id
                    ).first()
                    
                    if work_order:
                        context_parts.append(f"当前工单信息:")
                        context_parts.append(f"工单号: {work_order.order_id}")
                        context_parts.append(f"标题: {work_order.title}")
                        context_parts.append(f"描述: {work_order.description}")
                        context_parts.append(f"类别: {work_order.category}")
                        context_parts.append(f"优先级: {work_order.priority}")
                        context_parts.append(f"状态: {work_order.status}")
            except Exception as e:
                logger.error(f"获取工单信息失败: {e}")
        
        # 添加用户历史对话（优先从历史管理器获取）
        if user_id:
            # 尝试从历史管理器获取上下文
            history_context = self.history_manager.get_conversation_context(
                user_id=user_id,
                work_order_id=work_order_id,
                context_length=6
            )
            if history_context:
                context_parts.append("最近的对话历史:")
                context_parts.append(history_context)
            elif user_id in self.conversation_history:
                # 回退到内存中的历史
                recent_history = self.conversation_history[user_id][-6:]  # 最近3轮对话
                if recent_history:
                    context_parts.append("最近的对话历史:")
                    for msg in recent_history:
                        role = "用户" if msg["role"] == "user" else "助手"
                        context_parts.append(f"{role}: {msg['content']}")
        
        return "\n".join(context_parts) if context_parts else ""
    
    def _save_conversation(
        self,
        work_order_id: Optional[int],
        user_message: str,
        assistant_response: str,
        knowledge_used: str
    ) -> int:
        """保存对话记录"""
        try:
            with db_manager.get_session() as session:
                conversation = Conversation(
                    work_order_id=work_order_id,
                    user_message=user_message,
                    assistant_response=assistant_response,
                    knowledge_used=knowledge_used,
                    timestamp=datetime.now()
                )
                session.add(conversation)
                session.commit()
                return conversation.id
        except Exception as e:
            logger.error(f"保存对话记录失败: {e}")
            return 0
    
    def _calculate_confidence(self, knowledge_results: List[Dict[str, Any]]) -> float:
        """计算回复置信度"""
        if not knowledge_results:
            return 0.5  # 默认置信度
        
        # 基于知识库匹配度和置信度计算
        max_similarity = max(result.get("similarity_score", 0) for result in knowledge_results)
        avg_confidence = sum(result.get("confidence_score", 0) for result in knowledge_results) / len(knowledge_results)
        
        # 综合评分
        confidence = (max_similarity * 0.6 + avg_confidence * 0.4)
        return min(confidence, 1.0)
    
    def create_work_order(
        self,
        title: str,
        description: str,
        category: str,
        priority: str = "medium"
    ) -> Dict[str, Any]:
        """创建工单"""
        try:
            with db_manager.get_session() as session:
                work_order = WorkOrder(
                    order_id=f"WO{datetime.now().strftime('%Y%m%d%H%M%S')}",
                    title=title,
                    description=description,
                    category=category,
                    priority=priority,
                    status="open",
                    created_at=datetime.now()
                )
                session.add(work_order)
                session.commit()
                
                logger.info(f"创建工单成功: {work_order.order_id}")
                return {
                    "work_order_id": work_order.id,
                    "order_id": work_order.order_id,
                    "status": "success"
                }
                
        except Exception as e:
            logger.error(f"创建工单失败: {e}")
            return {"error": f"创建失败: {str(e)}"}
    
    def update_work_order(
        self,
        work_order_id: int,
        status: Optional[str] = None,
        resolution: Optional[str] = None,
        satisfaction_score: Optional[float] = None
    ) -> bool:
        """更新工单"""
        try:
            with db_manager.get_session() as session:
                work_order = session.query(WorkOrder).filter(
                    WorkOrder.id == work_order_id
                ).first()
                
                if not work_order:
                    return False
                
                if status:
                    work_order.status = status
                if resolution:
                    work_order.resolution = resolution
                if satisfaction_score is not None:
                    work_order.satisfaction_score = satisfaction_score
                
                work_order.updated_at = datetime.now()
                session.commit()
                
                # 如果工单已解决，学习知识
                if status == "resolved" and resolution:
                    self.knowledge_manager.learn_from_work_order(work_order_id)
                
                logger.info(f"更新工单成功: {work_order_id}")
                return True
                
        except Exception as e:
            logger.error(f"更新工单失败: {e}")
            return False
    
    def get_conversation_history(self, work_order_id: int) -> List[Dict[str, Any]]:
        """获取工单对话历史"""
        try:
            with db_manager.get_session() as session:
                conversations = session.query(Conversation).filter(
                    Conversation.work_order_id == work_order_id
                ).order_by(Conversation.timestamp).all()
                
                return [
                    {
                        "id": conv.id,
                        "user_message": conv.user_message,
                        "assistant_response": conv.assistant_response,
                        "timestamp": conv.timestamp.isoformat(),
                        "confidence_score": conv.confidence_score
                    }
                    for conv in conversations
                ]
                
        except Exception as e:
            logger.error(f"获取对话历史失败: {e}")
            return []
    
    def get_user_conversation_history(
        self,
        user_id: str,
        work_order_id: Optional[int] = None,
        limit: int = 10,
        offset: int = 0
    ) -> List[Dict[str, Any]]:
        """获取用户对话历史（支持分页）"""
        try:
            return self.history_manager.get_conversation_history(
                user_id=user_id,
                work_order_id=work_order_id,
                limit=limit,
                offset=offset
            )
        except Exception as e:
            logger.error(f"获取用户对话历史失败: {e}")
            return []
    
    def delete_conversation(self, conversation_id: int) -> bool:
        """删除对话记录"""
        try:
            return self.history_manager.delete_conversation(conversation_id)
        except Exception as e:
            logger.error(f"删除对话记录失败: {e}")
            return False
    
    def delete_user_conversations(self, user_id: str, work_order_id: Optional[int] = None) -> int:
        """删除用户的所有对话记录"""
        try:
            return self.history_manager.delete_user_conversations(user_id, work_order_id)
        except Exception as e:
            logger.error(f"删除用户对话记录失败: {e}")
            return 0
    
    def get_conversation_stats(self, user_id: str, work_order_id: Optional[int] = None) -> Dict[str, Any]:
        """获取对话统计信息"""
        try:
            return self.history_manager.get_conversation_stats(user_id, work_order_id)
        except Exception as e:
            logger.error(f"获取对话统计失败: {e}")
            return {}
    
    def get_token_usage_stats(self, user_id: str, days: int = 7) -> Dict[str, Any]:
        """获取Token使用统计"""
        try:
            return self.token_monitor.get_user_token_stats(user_id, days)
        except Exception as e:
            logger.error(f"获取Token使用统计失败: {e}")
            return {}
    
    def get_ai_performance_stats(self, model_name: str = None, hours: int = 24) -> Dict[str, Any]:
        """获取AI性能统计"""
        try:
            if model_name:
                return self.ai_success_monitor.get_model_performance(model_name, hours)
            else:
                return self.ai_success_monitor.get_system_performance(hours)
        except Exception as e:
            logger.error(f"获取AI性能统计失败: {e}")
            return {}
