"""
对话式决策支持系统 - 实现多轮对话，提供个性化推荐
"""
from typing import Dict, List, Optional, Tuple, Any
import json
from datetime import datetime

class DialogManager:
    """对话管理器 - 支持多轮交互"""

    def __init__(self):
        self.conversation_history = []
        self.user_preferences = {}
        self.current_state = "initial"
        
        # 追问策略
        self.questions = {
            "initial": [
                "请问是送给谁的？（例如：妈妈、女友、同事）",
                "是什么场合呢？（例如：生日、情人节、节日）",
                "预算大概多少？（例如：500元左右、1000-2000元）"
            ],
            "basic_info_collected": [
                "对方有什么特别的兴趣爱好吗？（例如：运动、音乐、旅行）",
                "对方是偏向实用型还是浪漫型？",
                "想要追求惊喜效果还是心意表达？"
            ],
            "preference_known": [
                "对方有没有什么过敏或忌讳的东西？",
                "之前送过什么礼物，对方特别喜欢？",
                "想要什么类型的礼物？（例如：电子产品、珠宝、家居用品）"
            ]
        }
        
        # 状态转移
        self.state_transitions = {
            "initial": ["basic_info_collected"],
            "basic_info_collected": ["preference_known", "ready_to_recommend"],
            "preference_known": ["ready_to_recommend"],
            "ready_to_recommend": ["waiting_feedback"],
            "waiting_feedback": ["refining_recommendation", "finalizing"],
            "finalizing": ["complete"]
        }
        
        # 用户情感状态
        self.emotion_states = {
            "confident": "用户明确知道需求",
            "hesitant": "用户犹豫不决，需要引导",
            "anxious": "用户担心送错礼物",
            "surprised": "用户对推荐感到意外",
            "satisfied": "用户对推荐满意"
        }
        
        # 用户模型
        self.user_model = {
            "style_preference": None,  # 实用/浪漫/惊喜/传统
            "budget_priority": None,   # 性价比/心意/面子
            "risk_tolerance": None,    # 保守/中等/大胆
            "decision_speed": None,    # 快速/谨慎
        }

    def process_message(self, user_input: str) -> Tuple[str, Dict]:
        """
        处理用户输入，返回回复和状态
        
        Args:
            user_input: 用户输入
            
        Returns:
            Tuple[回复内容, 当前状态]
        """
        # 保存对话历史
        self.conversation_history.append({
            "role": "user",
            "content": user_input,
            "timestamp": datetime.now().isoformat()
        })
        
        # 分析用户输入
        analysis = self._analyze_user_input(user_input)
        
        # 更新用户偏好
        self._update_user_preferences(analysis)
        
        # 确定下一步行动
        response, next_state = self._determine_next_action(analysis)
        
        # 更新状态
        self.current_state = next_state
        
        # 保存助手回复
        self.conversation_history.append({
            "role": "assistant",
            "content": response,
            "timestamp": datetime.now().isoformat()
        })
        
        return response, {
            "state": self.current_state,
            "preferences": self.user_preferences,
            "analysis": analysis
        }

    def _analyze_user_input(self, user_input: str) -> Dict:
        """分析用户输入，提取关键信息"""
        analysis = {
            "entities": [],
            "intent": None,
            "emotion": None,
            "preferences": {}
        }
        
        # 提取实体
        entities = self._extract_entities(user_input)
        analysis["entities"] = entities
        
        # 识别意图
        intent = self._classify_intent(user_input)
        analysis["intent"] = intent
        
        # 分析情感
        emotion = self._detect_emotion(user_input)
        analysis["emotion"] = emotion
        
        # 提取偏好
        preferences = self._extract_preferences(user_input)
        analysis["preferences"] = preferences
        
        return analysis

    def _extract_entities(self, text: str) -> List[Dict]:
        """提取实体（关系、场合、预算等）"""
        entities = []
        
        # 关系实体
        relation_keywords = {
            "妈妈", "爸爸", "父母", "女友", "男朋友", "老公", "老婆", "伴侣", "朋友",
            "闺蜜", "兄弟", "姐妹", "同事", "领导", "客户", "老师", "长辈", "孩子"
        }
        
        for keyword in relation_keywords:
            if keyword in text:
                entities.append({
                    "type": "relation",
                    "value": keyword,
                    "confidence": 0.9
                })
        
        # 场合实体
        occasion_keywords = {
            "生日", "情人节", "纪念日", "母亲节", "父亲节", "教师节", "春节", "中秋",
            "圣诞节", "新年", "乔迁", "结婚", "道歉", "感谢", "表白", "升职", "毕业"
        }
        
        for keyword in occasion_keywords:
            if keyword in text:
                entities.append({
                    "type": "occasion",
                    "value": keyword,
                    "confidence": 0.9
                })
        
        # 预算实体
        import re
        budget_patterns = [
            r'(\d+)\s*元',  # 500元
            r'(\d+)\s*块钱',  # 500块钱
            r'(\d+)[-~到]\s*(\d+)\s*元',  # 500-1000元
            r'预算\s*(\d+)',  # 预算500
        ]
        
        for pattern in budget_patterns:
            matches = re.findall(pattern, text)
            for match in matches:
                if isinstance(match, tuple):
                    min_budget = int(match[0])
                    max_budget = int(match[1]) if len(match) > 1 else min_budget
                    entities.append({
                        "type": "budget",
                        "value": [min_budget, max_budget],
                        "confidence": 0.8
                    })
                else:
                    entities.append({
                        "type": "budget",
                        "value": [int(match), int(match)],
                        "confidence": 0.8
                    })
        
        # 兴趣实体
        interest_keywords = {
            "运动", "健身", "音乐", "电影", "旅行", "摄影", "阅读", "美食", "烹饪",
            "游戏", "科技", "数码", "美妆", "时尚", "手工", "绘画", "园艺"
        }
        
        for keyword in interest_keywords:
            if keyword in text:
                entities.append({
                    "type": "interest",
                    "value": keyword,
                    "confidence": 0.7
                })
        
        return entities

    def _classify_intent(self, text: str) -> str:
        """分类用户意图"""
        text_lower = text.lower()
        
        if any(word in text_lower for word in ["推荐", "建议", "送什么", "选什么"]):
            return "request_recommendation"
        elif any(word in text_lower for word in ["不好", "不喜欢", "不合适", "换一个"]):
            return "reject_recommendation"
        elif any(word in text_lower for word in ["可以", "不错", "喜欢", "还行"]):
            return "accept_recommendation"
        elif any(word in text_lower for word in ["不知道", "不确定", "纠结", "犹豫"]):
            return "express_hesitation"
        elif any(word in text_lower for word in ["谢谢", "感谢", "帮了大忙"]):
            return "express_gratitude"
        elif any(word in text_lower for word in ["怎么送", "怎么说", "祝福语"]):
            return "request_advice"
        else:
            return "provide_information"

    def _detect_emotion(self, text: str) -> str:
        """检测用户情感"""
        text_lower = text.lower()
        
        # 焦虑词
        anxiety_words = {"担心", "怕", "焦虑", "紧张", "会不会", "行不行"}
        if any(word in text_lower for word in anxiety_words):
            return "anxious"
        
        # 犹豫词
        hesitant_words = {"不知道", "不确定", "纠结", "犹豫", "都可以", "随便"}
        if any(word in text_lower for word in hesitant_words):
            return "hesitant"
        
        # 积极词
        positive_words = {"好", "喜欢", "开心", "满意", "很棒", "不错"}
        if any(word in text_lower for word in positive_words):
            return "satisfied"
        
        # 中性
        return "neutral"

    def _extract_preferences(self, text: str) -> Dict:
        """提取用户偏好"""
        preferences = {}
        text_lower = text.lower()
        
        # 风格偏好
        if any(word in text_lower for word in ["实用", "实用型", "实用一点"]):
            preferences["style"] = "实用型"
        elif any(word in text_lower for word in ["浪漫", "浪漫型", "浪漫一点"]):
            preferences["style"] = "浪漫型"
        elif any(word in text_lower for word in ["惊喜", "惊喜型", "惊喜一点"]):
            preferences["style"] = "惊喜型"
        elif any(word in text_lower for word in ["传统", "传统型", "传统一点"]):
            preferences["style"] = "传统型"
        
        # 预算优先级
        if any(word in text_lower for word in ["便宜", "实惠", "性价比"]):
            preferences["budget_priority"] = "性价比"
        elif any(word in text_lower for word in ["心意", "心意重要", "不在乎价格"]):
            preferences["budget_priority"] = "心意"
        elif any(word in text_lower for word in ["体面", "面子", "高档"]):
            preferences["budget_priority"] = "面子"
        
        # 风险承受度
        if any(word in text_lower for word in ["保守", "安全", "稳妥"]):
            preferences["risk_tolerance"] = "保守"
        elif any(word in text_lower for word in ["大胆", "冒险", "创新"]):
            preferences["risk_tolerance"] = "大胆"
        
        return preferences

    def _update_user_preferences(self, analysis: Dict):
        """更新用户偏好"""
        # 更新实体信息
        for entity in analysis["entities"]:
            entity_type = entity["type"]
            entity_value = entity["value"]
            
            if entity_type == "relation":
                self.user_preferences["relation"] = entity_value
            elif entity_type == "occasion":
                self.user_preferences["occasion"] = entity_value
            elif entity_type == "budget":
                self.user_preferences["budget_min"] = entity_value[0]
                self.user_preferences["budget_max"] = entity_value[1]
            elif entity_type == "interest":
                if "interests" not in self.user_preferences:
                    self.user_preferences["interests"] = []
                if entity_value not in self.user_preferences["interests"]:
                    self.user_preferences["interests"].append(entity_value)
        
        # 更新偏好
        for key, value in analysis["preferences"].items():
            self.user_preferences[key] = value
        
        # 更新用户模型
        if "style" in analysis["preferences"]:
            self.user_model["style_preference"] = analysis["preferences"]["style"]
        if "budget_priority" in analysis["preferences"]:
            self.user_model["budget_priority"] = analysis["preferences"]["budget_priority"]
        if "risk_tolerance" in analysis["preferences"]:
            self.user_model["risk_tolerance"] = analysis["preferences"]["risk_tolerance"]

    def _determine_next_action(self, analysis: Dict) -> Tuple[str, str]:
        """确定下一步行动"""
        current_state = self.current_state
        
        # 根据意图和情感决定响应
        intent = analysis["intent"]
        emotion = analysis["emotion"]
        
        if current_state == "initial":
            # 初始状态，收集基本信息
            return self._ask_initial_questions()
        
        elif current_state == "basic_info_collected":
            # 已收集基本信息，询问偏好
            return self._ask_preference_questions()
        
        elif current_state == "preference_known":
            # 偏好已知，准备推荐
            return self._prepare_recommendation()
        
        elif current_state == "ready_to_recommend":
            # 推荐礼物
            return self._provide_recommendation()
        
        elif current_state == "waiting_feedback":
            # 等待反馈
            if intent == "reject_recommendation":
                return self._handle_rejection()
            elif intent == "accept_recommendation":
                return self._handle_acceptance()
            else:
                return self._ask_for_feedback()
        
        else:
            # 默认响应
            return self._get_default_response(analysis)

    def _ask_initial_questions(self) -> Tuple[str, str]:
        """询问初始问题"""
        if "relation" not in self.user_preferences:
            return self.questions["initial"][0], "initial"
        elif "occasion" not in self.user_preferences:
            return self.questions["initial"][1], "initial"
        elif "budget_min" not in self.user_preferences:
            return self.questions["initial"][2], "initial"
        else:
            # 检查是否已收集足够信息
            collected_info = [
                "relation" in self.user_preferences,
                "occasion" in self.user_preferences,
                "budget_min" in self.user_preferences
            ]
            if all(collected_info):
                return "基本信息已收集，接下来问问您的偏好。", "basic_info_collected"
            else:
                # 继续询问缺失的信息
                if not collected_info[0]:
                    return self.questions["initial"][0], "initial"
                elif not collected_info[1]:
                    return self.questions["initial"][1], "initial"
                else:
                    return self.questions["initial"][2], "initial"

    def _ask_preference_questions(self) -> Tuple[str, str]:
        """询问偏好问题 - 优化版：更早进入推荐"""
        # 检查基本信息是否完整
        required_info = ["relation", "occasion", "budget_min"]
        has_required_info = all(key in self.user_preferences for key in required_info)
        
        if not has_required_info:
            # 基本信息不完整，继续询问
            return "还需要一些基本信息才能推荐。请问预算大概多少？", "basic_info_collected"
        
        # 检查已收集的偏好信息
        collected_preferences = []
        if "interests" in self.user_preferences and len(self.user_preferences["interests"]) > 0:
            collected_preferences.append("兴趣")
        if "style" in self.user_preferences:
            collected_preferences.append("风格偏好")
        if "risk_tolerance" in self.user_preferences:
            collected_preferences.append("风险偏好")
        
        # 如果已经收集了足够信息，提前进入推荐
        if len(collected_preferences) >= 1:
            # 已经收集了至少1个偏好，可以推荐了
            summary = "已了解"
            if collected_preferences:
                summary += "：" + "、".join(collected_preferences)
            return f"{summary}，我来为您推荐礼物。", "preference_known"
        
        # 根据缺失的信息询问
        if "interests" not in self.user_preferences or len(self.user_preferences["interests"]) == 0:
            return self.questions["basic_info_collected"][0], "basic_info_collected"
        elif "style" not in self.user_preferences:
            return self.questions["basic_info_collected"][1], "basic_info_collected"
        else:
            return self.questions["basic_info_collected"][2], "basic_info_collected"

    def _prepare_recommendation(self) -> Tuple[str, str]:
        """准备推荐"""
        summary = self._create_preference_summary()
        return f"{summary}\n\n根据您的需求，我为您推荐以下礼物：", "ready_to_recommend"

    def _provide_recommendation(self) -> Tuple[str, str]:
        """提供推荐"""
        # 这里应该调用实际的推荐系统
        # 暂时返回示例
        example_recommendations = [
            {"name": "智能手表", "price": 899, "reason": "科技实用，关心健康"},
            {"name": "手工相册", "price": 199, "reason": "珍藏回忆，心意满满"},
            {"name": "香薰套装", "price": 299, "reason": "放松身心，品质生活"},
        ]
        
        recommendations_text = "\n".join([
            f"1. {rec['name']}（{rec['price']}元） - {rec['reason']}"
            for rec in example_recommendations
        ])
        
        question = "\n\n您觉得这些推荐如何？有没有特别喜欢的，或者想要调整的？"
        
        return recommendations_text + question, "waiting_feedback"

    def _handle_rejection(self) -> Tuple[str, str]:
        """处理拒绝"""
        responses = [
            "没关系，我们换一种思路。您能告诉我哪些方面不满意吗？",
            "好的，我明白了。您希望更注重实用还是更注重惊喜？",
            "我们来调整一下。您觉得预算范围需要调整吗？",
        ]
        
        import random
        return random.choice(responses), "basic_info_collected"

    def _handle_acceptance(self) -> Tuple[str, str]:
        """处理接受"""
        responses = [
            "太好了！需要我帮您想一句祝福语吗？",
            "很高兴您喜欢！要我帮您包装礼物建议吗？",
            "完美选择！还有其他需要帮助的吗？",
        ]
        
        import random
        return random.choice(responses), "finalizing"

    def _ask_for_feedback(self) -> Tuple[str, str]:
        """请求反馈"""
        return "您对这些推荐有什么想法吗？有没有特别喜欢的？", "waiting_feedback"

    def _get_default_response(self, analysis: Dict) -> Tuple[str, str]:
        """获取默认响应"""
        if analysis["emotion"] == "anxious":
            return "别担心，选礼物确实不容易。我们一步步来，一定能找到合适的礼物。", self.current_state
        elif analysis["emotion"] == "hesitant":
            return "我理解您的犹豫。我们多讨论几个选项，您慢慢选。", self.current_state
        else:
            return "好的，我明白了。我们继续讨论礼物选择。", self.current_state

    def _create_preference_summary(self) -> str:
        """创建偏好总结"""
        parts = ["根据我们之前的对话，我了解到："]
        
        if "relation" in self.user_preferences:
            parts.append(f"• 送给：{self.user_preferences['relation']}")
        
        if "occasion" in self.user_preferences:
            parts.append(f"• 场合：{self.user_preferences['occasion']}")
        
        if "budget_min" in self.user_preferences:
            budget = f"{self.user_preferences['budget_min']}"
            if "budget_max" in self.user_preferences and self.user_preferences['budget_max'] != self.user_preferences['budget_min']:
                budget += f"-{self.user_preferences['budget_max']}"
            parts.append(f"• 预算：{budget}元")
        
        if "interests" in self.user_preferences and self.user_preferences["interests"]:
            parts.append(f"• 兴趣：{', '.join(self.user_preferences['interests'])}")
        
        if "style" in self.user_preferences:
            parts.append(f"• 风格偏好：{self.user_preferences['style']}")
        
        return "\n".join(parts)

    def get_conversation_summary(self) -> str:
        """获取对话总结"""
        if not self.conversation_history:
            return "暂无对话记录"
        
        summary = ["对话记录："]
        for msg in self.conversation_history[-5:]:  # 最近5条
            role = "用户" if msg["role"] == "user" else "助手"
            summary.append(f"{role}：{msg['content'][:50]}...")
        
        return "\n".join(summary)

    def reset_conversation(self):
        """重置对话"""
        self.conversation_history = []
        self.user_preferences = {}
        self.current_state = "initial"
        self.user_model = {
            "style_preference": None,
            "budget_priority": None,
            "risk_tolerance": None,
            "decision_speed": None,
        }


# 使用示例
if __name__ == "__main__":
    dialog = DialogManager()
    
    print("=== 对话式礼物推荐系统 ===\n")
    
    # 模拟对话
    test_messages = [
        "我想给妈妈选生日礼物",
        "预算500元左右吧",
        "她喜欢养花",
        "实用一点的",
        "这些推荐都不错，第一个智能手表挺好的"
    ]
    
    for msg in test_messages:
        print(f"用户：{msg}")
        response, state = dialog.process_message(msg)
        print(f"助手：{response}")
        print(f"状态：{state['state']}")
        print("-" * 50)
    
    print("\n=== 对话总结 ===")
    print(dialog.get_conversation_summary())
    
    print("\n=== 用户偏好 ===")
    print(json.dumps(dialog.user_preferences, indent=2, ensure_ascii=False))