"""
API入口 - 优化集成版（主文件）
整合了3个核心优化模块：
1. GiftFilterV2 - 增强禁忌过滤
2. BlessingGeneratorV2 - 个性化祝福语
3. DialogManager - 对话式决策支持

保持向后兼容性，同时提供新功能
"""
from typing import List, Dict, Optional, Union
from .recommender import Recommender
from .parser import InputParser
from .reason import ReasonGenerator
from .blessing_v2 import BlessingGeneratorV2
from .filter_v2 import GiftFilterV2
from .dialog_manager import DialogManager
from .output_formatter import OutputFormatter
from .preference import get_preference

class GiftAdvisor:
    """礼物推荐助手 - 优化集成版"""

    def __init__(self, user_id: str = "default", use_enhanced_features: bool = True):
        # 核心模块
        self.recommender = Recommender()
        self.parser = InputParser()
        self.reason_gen = ReasonGenerator()
        self.formatter = OutputFormatter()
        self.preference = get_preference()
        
        # 新模块（可选）
        self.use_enhanced = use_enhanced_features
        if use_enhanced_features:
            self.blessing_gen = BlessingGeneratorV2()
            self.filter_v2 = GiftFilterV2()
            self.dialog = DialogManager()
        else:
            from .blessing import BlessingGenerator
            from .filter import GiftFilter
            self.blessing_gen = BlessingGenerator()
            self.filter_v2 = GiftFilter()
            self.dialog = None
        
        # 用户状态
        self.user_id = user_id
        self.conversation_context = {
            "user_id": user_id,
            "preferences": {},
            "conversation_mode": "auto",
            "current_state": "initial" if use_enhanced_features else "direct",
            "last_recommendations": []
        }

    def recommend(
        self,
        relation: Optional[str] = None,
        occasion: Optional[str] = None,
        budget_min: Optional[int] = None,
        budget_max: Optional[int] = None,
        limit: int = 5,
        enhanced: bool = True
    ) -> Dict:
        """
        推荐礼物（增强版）

        Args:
            relation: 收礼人关系
            occasion: 场合
            budget_min: 最低预算
            budget_max: 最高预算
            limit: 返回数量
            enhanced: 是否使用增强功能

        Returns:
            推荐结果
        """
        # 获取推荐
        gifts = self.recommender.recommend(
            relation=relation,
            occasion=occasion,
            budget_min=budget_min,
            budget_max=budget_max,
            limit=limit * 2  # 获取更多用于过滤
        )

        # 应用增强禁忌过滤
        filtered_gifts = gifts
        taboo_report = {"summary": "未使用增强过滤"}
        
        if enhanced and self.use_enhanced:
            filtered_gifts, taboo_report = self.filter_v2.filter(
                gifts=gifts,
                relation=relation
            )
        
        # 如果过滤后礼物太少，放宽过滤
        if len(filtered_gifts) < limit:
            filtered_gifts = gifts[:limit]
        
        # 限制数量
        filtered_gifts = filtered_gifts[:limit]
        
        # 生成推荐结果
        recommendations = []
        for gift in filtered_gifts:
            # 生成推荐理由
            reason = self.reason_gen.generate(gift, relation, occasion)
            
            # 计算分数
            score = self._calculate_score(gift, budget_max)
            
            recommendations.append({
                "name": gift.get("name"),
                "price": gift.get("price"),
                "reason": reason,
                "score": score,
                "original_reason": gift.get("reason", "")
            })
        
        # 按分数排序
        recommendations.sort(key=lambda x: x["score"], reverse=True)
        
        # 生成祝福语
        if enhanced and self.use_enhanced:
            # 使用增强版祝福语
            if recommendations:
                top_gift_name = recommendations[0]["name"]
                blessing = self.blessing_gen.generate(
                    occasion=occasion,
                    relation=relation,
                    gift_name=top_gift_name,
                    style="标准版"
                )
            else:
                blessing = self.blessing_gen.generate(occasion)
            
            # 获取多个祝福语选项
            blessing_options = self.blessing_gen.generate_multiple_options(
                occasion=occasion,
                relation=relation,
                count=3
            )
        else:
            # 使用基础版祝福语
            blessing = self.blessing_gen.generate(occasion)
            blessing_options = []
        
        return {
            "success": True,
            "query": {
                "relation": relation,
                "occasion": occasion,
                "budget": f"{budget_min or '?'}-{budget_max or '?'}元",
            },
            "recommendations": recommendations,
            "blessing": blessing,
            "blessing_options": blessing_options if blessing_options else None,
            "taboo_report": taboo_report,
            "enhanced": enhanced,
            "count": len(recommendations),
        }

    def parse_and_recommend(self, text: str, limit: int = 5) -> Dict:
        """
        解析自然语言并推荐（兼容旧版）

        Args:
            text: 用户输入文本
            limit: 返回数量

        Returns:
            推荐结果
        """
        # 检测是否是"换一个"
        if self._is_change_request(text):
            return self._handle_change_request()
        
        # 检测是否是对话模式
        if self.use_enhanced and self._should_use_dialog(text):
            return self.process_message(text)

        # 解析输入
        parsed = self.parser.parse(text)

        # 如果需要追问
        if parsed.get("needs_clarification"):
            return {
                "success": False,
                "needs_clarification": True,
                "missing_fields": parsed.get("missing_fields", []),
                "clarification_questions": self.parser.get_clarification_questions(
                    parsed.get("missing_fields", [])
                ),
                "parsed": parsed,
            }
        
        # 保存查询
        self.preference.set_last_query(parsed, self.user_id)
        self.preference.clear_shown_gifts(self.user_id)

        # 推荐
        result = self.recommend(
            relation=parsed.get("relation"),
            occasion=parsed.get("occasion"),
            budget_min=parsed.get("budget_min"),
            budget_max=parsed.get("budget_max"),
            limit=limit,
            enhanced=True
        )
        
        # 记录已展示的礼物
        for gift in result.get("recommendations", []):
            self.preference.add_shown_gift(gift["name"], self.user_id)
        
        return result

    def process_message(self, user_input: str) -> Dict:
        """
        处理用户消息（对话式入口）
        
        Args:
            user_input: 用户输入文本
            
        Returns:
            处理结果
        """
        if not self.use_enhanced or not self.dialog:
            return {
                "success": False,
                "message": "对话功能未启用",
                "suggestion": "请使用 parse_and_recommend 或 recommend 方法"
            }
        
        # 对话管理器处理
        response, dialog_state = self.dialog.process_message(user_input)
        
        # 更新对话上下文
        self.conversation_context["current_state"] = dialog_state["state"]
        self.conversation_context["preferences"] = dialog_state["preferences"]
        
        # 根据状态决定是否生成推荐
        result = self._generate_response_based_on_state(response, dialog_state)
        
        # 添加对话状态信息
        result["dialog_state"] = {
            "state": dialog_state["state"],
            "emotion": dialog_state["analysis"].get("emotion"),
            "intent": dialog_state["analysis"].get("intent")
        }
        
        # 保存最后推荐
        if "recommendations" in result:
            self.conversation_context["last_recommendations"] = result["recommendations"]
        
        return result

    def _generate_response_based_on_state(self, response: str, dialog_state: Dict) -> Dict:
        """根据对话状态生成响应"""
        state = dialog_state["state"]
        
        if state == "ready_to_recommend":
            # 生成推荐
            preferences = dialog_state["preferences"]
            return self.recommend(
                relation=preferences.get("relation"),
                occasion=preferences.get("occasion"),
                budget_min=preferences.get("budget_min"),
                budget_max=preferences.get("budget_max"),
                enhanced=True
            )
        elif state in ["initial", "basic_info_collected", "preference_known"]:
            # 继续对话
            return {
                "success": True,
                "message": response,
                "type": "question"
            }
        else:
            # 其他状态
            return {
                "success": True,
                "message": response,
                "type": "response"
            }

    def _is_change_request(self, text: str) -> bool:
        """检测是否是换一个的请求"""
        change_keywords = ["换一个", "换一个吧", "再来一个", "换换", "还有吗", "别的"]
        has_last_query = self.preference.get_last_query(self.user_id) is not None
        return any(kw in text for kw in change_keywords) and has_last_query

    def _handle_change_request(self) -> Dict:
        """处理换一个请求"""
        last_query = self.preference.get_last_query(self.user_id)
        if not last_query:
            return {
                "success": False,
                "message": "没有之前的查询记录，请先告诉我送礼需求～"
            }
        
        # 获取已展示的礼物
        shown_gifts = self.preference.get_shown_gifts(self.user_id)
        
        # 获取更多推荐
        all_gifts = self.recommender.recommend(
            relation=last_query.get("relation"),
            occasion=last_query.get("occasion"),
            budget_min=last_query.get("budget_min"),
            budget_max=last_query.get("budget_max"),
            limit=20
        )
        
        # 过滤已展示的
        new_gifts = [g for g in all_gifts if g["name"] not in shown_gifts]
        
        # 如果没有新的，清空历史重来
        if not new_gifts:
            self.preference.clear_shown_gifts(self.user_id)
            new_gifts = all_gifts
        
        # 应用增强禁忌过滤
        if self.use_enhanced:
            new_gifts, _ = self.filter_v2.filter(
                gifts=new_gifts,
                relation=last_query.get("relation")
            )
        
        # 生成推荐
        recommendations = []
        for gift in new_gifts[:5]:
            reason = self.reason_gen.generate(gift, last_query.get("relation"))
            recommendations.append({
                "name": gift.get("name"),
                "price": gift.get("price"),
                "reason": reason,
                "score": self._calculate_score(gift, last_query.get("budget_max")),
            })
            self.preference.add_shown_gift(gift["name"], self.user_id)

        # 生成祝福语
        if self.use_enhanced:
            blessing = self.blessing_gen.generate(
                occasion=last_query.get("occasion"),
                relation=last_query.get("relation")
            )
        else:
            blessing = self.blessing_gen.generate(last_query.get("occasion"))

        return {
            "success": True,
            "query": {
                "relation": last_query.get("relation"),
                "occasion": last_query.get("occasion"),
                "budget": f"{last_query.get('budget_min') or 0}-{last_query.get('budget_max') or '不限'}",
            },
            "recommendations": recommendations,
            "blessing": blessing,
            "count": len(recommendations),
        }

    def _should_use_dialog(self, text: str) -> bool:
        """判断是否使用对话模式"""
        # 如果文本简短，可能开启对话
        if len(text) < 20:
            return True
        
        # 如果包含对话关键词
        dialog_keywords = ["你好", "在吗", "帮我", "请问", "可以吗", "怎么样"]
        if any(kw in text for kw in dialog_keywords):
            return True
        
        # 如果当前已在对话中
        if self.conversation_context["current_state"] != "initial":
            return True
        
        return False

    def _calculate_score(self, gift: Dict, budget_max: Optional[int] = None) -> int:
        """
        计算推荐分数

        Args:
            gift: 礼物信息
            budget_max: 最高预算

        Returns:
            分数（1-100）
        """
        score = 80  # 基础分

        # 价格适中性加分
        price = gift.get("price", 0)
        if budget_max:
            ratio = price / budget_max
            if 0.3 <= ratio <= 0.7:
                score += 10  # 价格适中加分

        # 有推荐理由加分
        if gift.get("reason"):
            score += 5

        # 限制在100分以内
        return min(score, 100)

    def get_formatted_result(self, text: str) -> str:
        """
        获取格式化后的推荐结果

        Args:
            text: 用户输入

        Returns:
            格式化后的推荐文本
        """
        result = self.parse_and_recommend(text)
        return self.formatter.format_recommendation(result)

    def explain_taboo(self, gift_name: str, relation: str = None) -> Dict:
        """
        解释礼物禁忌
        
        Args:
            gift_name: 礼物名称
            relation: 收礼人关系
            
        Returns:
            禁忌解释
        """
        if not self.use_enhanced:
            return {
                "success": False,
                "message": "增强禁忌功能未启用"
            }
        
        explanation = self.filter_v2.explain_taboo(gift_name, relation)
        alternatives = self.filter_v2.get_safe_alternatives(gift_name)
        
        return {
            "success": True,
            "gift_name": gift_name,
            "explanation": explanation,
            "alternatives": alternatives,
            "has_taboo": bool(explanation and "暂无发现禁忌" not in explanation)
        }

    def get_blessing_options(
        self,
        occasion: str,
        relation: str = None,
        gift_name: str = None,
        count: int = 3
    ) -> Dict:
        """
        获取祝福语选项
        
        Args:
            occasion: 场合
            relation: 关系
            gift_name: 礼物名称
            count: 选项数量
            
        Returns:
            祝福语选项
        """
        if not self.use_enhanced:
            return {
                "success": False,
                "message": "增强祝福语功能未启用"
            }
        
        options = self.blessing_gen.generate_multiple_options(
            occasion=occasion,
            relation=relation,
            gift_name=gift_name,
            count=count
        )
        
        return {
            "success": True,
            "occasion": occasion,
            "relation": relation,
            "gift_name": gift_name,
            "options": options
        }

    def reset_conversation(self):
        """重置对话"""
        if self.dialog:
            self.dialog.reset_conversation()
        
        self.conversation_context = {
            "user_id": self.user_id,
            "preferences": {},
            "conversation_mode": "auto",
            "current_state": "initial" if self.use_enhanced else "direct",
            "last_recommendations": []
        }
        
        return {
            "success": True,
            "message": "对话已重置，重新开始吧！"
        }


# 便捷函数（保持向后兼容）
def recommend_gift(
    relation: str = None,
    occasion: str = None,
    budget_min: int = None,
    budget_max: int = None,
    enhanced: bool = True
) -> Dict:
    """
    便捷推荐函数

    示例:
        result = recommend_gift("妈妈", "生日", 200, 1000)
        result = recommend_gift("女友", "情人节", budget_max=500, enhanced=True)
    """
    advisor = GiftAdvisor(use_enhanced_features=enhanced)
    return advisor.recommend(relation, occasion, budget_min, budget_max, enhanced=enhanced)


def parse_and_recommend(text: str, enhanced: bool = True) -> Dict:
    """
    解析自然语言并推荐

    示例:
        result = parse_and_recommend("送妈妈的生日礼物，预算500元左右")
        result = parse_and_recommend("送女友情人节礼物", enhanced=True)
    """
    advisor = GiftAdvisor(use_enhanced_features=enhanced)
    return advisor.parse_and_recommend(text)


def get_formatted_recommendation(text: str, enhanced: bool = True) -> str:
    """
    获取格式化后的推荐结果

    示例:
        text = get_formatted_recommendation("送女朋友生日礼物，预算500元")
        print(text)
    """
    advisor = GiftAdvisor(use_enhanced_features=enhanced)
    return advisor.get_formatted_result(text)


# 新增功能
def explain_gift_taboo(gift_name: str, relation: str = None) -> Dict:
    """
    解释礼物禁忌
    
    示例:
        result = explain_gift_taboo("精美时钟", "长辈")
        print(result['explanation'])
    """
    advisor = GiftAdvisor(use_enhanced_features=True)
    return advisor.explain_taboo(gift_name, relation)


def get_blessing_options(
    occasion: str,
    relation: str = None,
    gift_name: str = None,
    count: int = 3
) -> Dict:
    """
    获取祝福语选项
    
    示例:
        result = get_blessing_options("生日", "妈妈", "鲜花", 3)
        for option in result['options']:
            print(option)
    """
    advisor = GiftAdvisor(use_enhanced_features=True)
    return advisor.get_blessing_options(occasion, relation, gift_name, count)


def start_conversation(user_id: str = "default") -> GiftAdvisor:
    """
    开始对话式推荐
    
    示例:
        advisor = start_conversation("user123")
        result1 = advisor.process_message("我想给妈妈选生日礼物")
        result2 = advisor.process_message("预算500元")
    """
    return GiftAdvisor(user_id=user_id, use_enhanced_features=True)