"""
API入口 - 主接口模块
优化版：支持追问、友好输出、用户偏好记忆
"""
from typing import List, Dict, Optional
from .recommender import Recommender
from .parser import InputParser
from .reason import ReasonGenerator
from .blessing import BlessingGenerator
from .output_formatter import OutputFormatter
from .preference import get_preference

class GiftAdvisor:
    """礼物推荐助手"""

    def __init__(self, user_id: str = "default"):
        self.recommender = Recommender()
        self.parser = InputParser()
        self.reason_gen = ReasonGenerator()
        self.blessing_gen = BlessingGenerator()
        self.formatter = OutputFormatter()
        self.preference = get_preference()
        self.user_id = user_id

    def recommend(
        self,
        relation: Optional[str] = None,
        occasion: Optional[str] = None,
        budget_min: Optional[int] = None,
        budget_max: Optional[int] = None,
        limit: int = 5
    ) -> Dict:
        """
        推荐礼物

        Args:
            relation: 收礼人关系
            occasion: 场合
            budget_min: 最低预算
            budget_max: 最高预算
            limit: 返回数量

        Returns:
            推荐结果
        """
        # 获取推荐
        gifts = self.recommender.recommend(
            relation=relation,
            occasion=occasion,
            budget_min=budget_min,
            budget_max=budget_max,
            limit=limit
        )

        # 生成推荐理由和祝福语
        recommendations = []
        for gift in gifts:
            reason = self.reason_gen.generate(gift, relation)
            recommendations.append({
                "name": gift.get("name"),
                "price": gift.get("price"),
                "reason": reason,
                "score": self._calculate_score(gift, budget_max),
            })

        blessing = self.blessing_gen.generate(occasion)

        return {
            "success": True,
            "query": {
                "relation": relation,
                "occasion": occasion,
                "budget": f"{budget_min or 0}-{budget_max or '不限'}",
            },
            "recommendations": recommendations,
            "blessing": blessing,
            "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()

        # 解析输入
        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
        )
        
        # 记录已展示的礼物
        for gift in result.get("recommendations", []):
            self.preference.add_shown_gift(gift["name"], self.user_id)
        
        return result

    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
        
        # 生成推荐
        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)

        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 _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 recommend_gift(
    relation: str = None,
    occasion: str = None,
    budget_min: int = None,
    budget_max: int = None
) -> Dict:
    """
    便捷推荐函数

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


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

    示例:
        result = parse_and_recommend("送妈妈的生日礼物，预算500元左右")
    """
    advisor = GiftAdvisor()
    return advisor.parse_and_recommend(text)


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

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