#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Keyword Analyzer
关键词分析器 - 从AI生成的内容中提取和分析关键词
"""

import logging
import re
from typing import List, Dict, Any, Optional, Set, Tuple
from dataclasses import dataclass
from datetime import datetime
from collections import Counter

from ..config import AlgorithmConfig
from ..core import AIService, PromptManager, JSONProcessor
from ..exceptions import ContentGenerationError

logger = logging.getLogger(__name__)


@dataclass
class KeywordResult:
    """关键词分析结果"""
    keywords: List[str]
    keyword_scores: Dict[str, float]
    categories: Dict[str, List[str]]
    search_suggestions: List[str]
    analysis_metadata: Dict[str, Any]
    analyzed_at: datetime
    
    def __post_init__(self):
        if self.analyzed_at is None:
            self.analyzed_at = datetime.now()
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'keywords': self.keywords,
            'keyword_scores': self.keyword_scores,
            'categories': self.categories,
            'search_suggestions': self.search_suggestions,
            'analysis_metadata': self.analysis_metadata,
            'analyzed_at': self.analyzed_at.isoformat() if self.analyzed_at else None
        }
    
    def get_top_keywords(self, limit: int = 10) -> List[str]:
        """获取评分最高的关键词"""
        sorted_keywords = sorted(
            self.keyword_scores.items(),
            key=lambda x: x[1],
            reverse=True
        )
        return [kw for kw, score in sorted_keywords[:limit]]


class KeywordAnalyzer:
    """
    关键词分析器
    从文本内容中提取关键词，生成搜索建议，并进行分类
    """
    
    def __init__(self, config: AlgorithmConfig):
        """
        初始化关键词分析器
        
        Args:
            config: 算法配置
        """
        self.config = config
        self.ai_service = AIService(config.ai_model)
        self.prompt_manager = PromptManager(config.prompts, config.resources)
        self.json_processor = JSONProcessor(
            enable_repair=config.content_generation.enable_json_repair,
            max_repair_attempts=config.content_generation.json_repair_attempts
        )
        
        # 获取任务特定的模型配置
        self.task_model_config = config.ai_model.get_task_config("keyword_analysis")
        
        # 预定义关键词类别
        self.keyword_categories = {
            '地理位置': ['城市', '省份', '景区', '地标', '区域'],
            '旅游类型': ['自驾游', '跟团游', '自由行', '亲子游', '蜜月游'],
            '景点类型': ['古镇', '山水', '海滨', '历史', '文化', '自然'],
            '活动体验': ['美食', '购物', '摄影', '徒步', '观光', '度假'],
            '时间季节': ['春游', '夏日', '秋景', '冬季', '节假日', '周末'],
            '消费水平': ['经济', '中档', '高端', '奢华', '性价比', '优惠']
        }
        
        # 停用词列表
        self.stop_words = {
            '的', '了', '是', '在', '有', '和', '就', '不', '人', '都', '一', '个', '上', '也', '很', '到', '说', '要', '去',
            '你', '会', '着', '没', '看', '好', '自己', '这', '那', '来', '可以', '时候', '我', '他', '她', '它', '们',
            '之', '与', '及', '或', '但', '而', '因为', '所以', '如果', '虽然', '然而', '因此', '于是', '总之'
        }
        
        logger.info("关键词分析器初始化完成")
    
    async def analyze_content(
        self,
        content: str,
        source_type: str = "general",
        enable_ai_analysis: bool = True
    ) -> KeywordResult:
        """
        分析内容中的关键词
        
        Args:
            content: 待分析的内容
            source_type: 内容源类型（general, topic, document, xhs_note等）
            enable_ai_analysis: 是否启用AI分析
            
        Returns:
            KeywordResult: 关键词分析结果
        """
        try:
            logger.info(f"开始分析关键词，内容长度: {len(content)}")
            
            # 1. 基础关键词提取
            basic_keywords = self._extract_basic_keywords(content)
            
            # 2. AI增强分析（可选）
            ai_keywords = []
            if enable_ai_analysis and len(content) > 50:
                ai_keywords = await self._ai_keyword_analysis(content, source_type)
            
            # 3. 合并和去重
            all_keywords = list(set(basic_keywords + ai_keywords))
            
            # 4. 关键词评分
            keyword_scores = self._score_keywords(all_keywords, content)
            
            # 5. 关键词分类
            categories = self._categorize_keywords(all_keywords)
            
            # 6. 生成搜索建议
            search_suggestions = self._generate_search_suggestions(all_keywords, content)
            
            # 7. 收集分析元数据
            analysis_metadata = {
                'content_length': len(content),
                'source_type': source_type,
                'ai_analysis_enabled': enable_ai_analysis,
                'basic_keywords_count': len(basic_keywords),
                'ai_keywords_count': len(ai_keywords),
                'total_keywords_count': len(all_keywords),
                'analysis_method': 'hybrid' if enable_ai_analysis else 'rule_based'
            }
            
            result = KeywordResult(
                keywords=all_keywords,
                keyword_scores=keyword_scores,
                categories=categories,
                search_suggestions=search_suggestions,
                analysis_metadata=analysis_metadata,
                analyzed_at=datetime.now()
            )
            
            logger.info(f"关键词分析完成，提取到 {len(all_keywords)} 个关键词")
            return result
            
        except Exception as e:
            error_msg = f"关键词分析失败: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise ContentGenerationError(error_msg)
    
    def _extract_basic_keywords(self, content: str) -> List[str]:
        """基础关键词提取（基于规则）"""
        keywords = []
        
        # 清理文本
        text = self._clean_text(content)
        
        # 1. 基于词频的关键词提取
        words = self._segment_words(text)
        word_freq = Counter(words)
        
        # 过滤停用词和短词
        filtered_words = []
        for word, freq in word_freq.items():
            if (len(word) >= 2 and 
                word not in self.stop_words and
                freq >= 2):  # 至少出现2次
                filtered_words.append(word)
        
        keywords.extend(filtered_words[:20])  # 取前20个高频词
        
        # 2. 基于正则表达式的特定模式提取
        patterns = [
            r'[\u4e00-\u9fa5]{2,4}市',     # 城市名
            r'[\u4e00-\u9fa5]{2,4}省',     # 省份名
            r'[\u4e00-\u9fa5]{2,6}景区',   # 景区名
            r'[\u4e00-\u9fa5]{2,6}古镇',   # 古镇名
            r'[\u4e00-\u9fa5]{2,6}山',     # 山名
            r'[\u4e00-\u9fa5]{2,6}湖',     # 湖名
            r'[\u4e00-\u9fa5]{2,6}寺',     # 寺庙名
            r'[\u4e00-\u9fa5]{2,6}公园',   # 公园名
        ]
        
        for pattern in patterns:
            matches = re.findall(pattern, text)
            keywords.extend(matches)
        
        # 3. 特定领域词汇识别
        travel_keywords = [
            '旅游', '旅行', '景点', '景区', '攻略', '游玩', '观光', '度假',
            '美食', '特产', '购物', '住宿', '交通', '门票', '路线', '推荐',
            '体验', '文化', '历史', '自然', '风景', '拍照', '打卡'
        ]
        
        for keyword in travel_keywords:
            if keyword in text:
                keywords.append(keyword)
        
        return list(set(keywords))
    
    def _clean_text(self, text: str) -> str:
        """清理文本"""
        # 移除HTML标签
        text = re.sub(r'<[^>]+>', '', text)
        
        # 移除特殊字符，保留中文、英文、数字
        text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]', ' ', text)
        
        # 移除多余空白
        text = re.sub(r'\s+', ' ', text).strip()
        
        return text
    
    def _segment_words(self, text: str) -> List[str]:
        """分词（简单实现）"""
        # 简单的基于空格和标点的分词
        words = []
        
        # 中文分词（简单的2-4字符组合）
        chinese_words = re.findall(r'[\u4e00-\u9fa5]{2,4}', text)
        words.extend(chinese_words)
        
        # 英文分词
        english_words = re.findall(r'[a-zA-Z]{2,}', text)
        words.extend(english_words)
        
        return words
    
    async def _ai_keyword_analysis(self, content: str, source_type: str) -> List[str]:
        """AI增强关键词分析"""
        try:
            system_prompt = self._get_keyword_system_prompt()
            user_prompt = self._build_keyword_user_prompt(content, source_type)
            
            result, tokens_input, tokens_output, elapsed_time = await self.ai_service.generate_text(
                system_prompt=system_prompt,
                user_prompt=user_prompt,
                stage="关键词分析",
                **self.task_model_config
            )
            
            # 解析AI返回的关键词
            keywords = self._parse_ai_keywords(result)
            
            logger.debug(f"AI关键词分析完成，提取到 {len(keywords)} 个关键词")
            return keywords
            
        except Exception as e:
            logger.warning(f"AI关键词分析失败: {e}")
            return []
    
    def _get_keyword_system_prompt(self) -> str:
        """获取关键词分析的系统提示词"""
        try:
            return self.prompt_manager.get_prompt("keyword_analysis", "system")
        except:
            return """你是一个专业的关键词分析专家，专门从旅游相关的文本内容中提取有价值的关键词。

你的任务是：
1. 从给定文本中提取最重要的关键词
2. 重点关注地理位置、景点名称、旅游活动、美食特产等
3. 过滤掉无意义的词汇
4. 按重要性排序

要求：
- 提取10-20个最有价值的关键词
- 优先提取专有名词和核心概念
- 避免过于通用的词汇
- 返回JSON格式的关键词列表"""
    
    def _build_keyword_user_prompt(self, content: str, source_type: str) -> str:
        """构建关键词分析的用户提示词"""
        return f"""请从以下{source_type}内容中提取关键词：

内容：
{content[:1000]}...

请提取最重要的关键词，并按照以下JSON格式返回：
{{
    "keywords": ["关键词1", "关键词2", "关键词3"],
    "location_keywords": ["地理位置相关关键词"],
    "activity_keywords": ["活动体验相关关键词"],
    "feature_keywords": ["特色特点相关关键词"]
}}

关键词要求：
1. 2-6个字符长度
2. 具有搜索价值
3. 与旅游相关
4. 避免过于通用的词汇"""
    
    def _parse_ai_keywords(self, ai_result: str) -> List[str]:
        """解析AI返回的关键词"""
        keywords = []
        
        try:
            # 使用JSON处理器解析
            parsed_data = self.json_processor.parse_llm_output(
                raw_output=ai_result,
                expected_fields=["keywords", "location_keywords", "activity_keywords", "feature_keywords"],
                required_fields=["keywords"]
            )
            
            if isinstance(parsed_data, dict):
                # 合并所有类型的关键词
                all_keywords = []
                for key in ["keywords", "location_keywords", "activity_keywords", "feature_keywords"]:
                    if key in parsed_data and isinstance(parsed_data[key], list):
                        all_keywords.extend(parsed_data[key])
                
                keywords = list(set(all_keywords))  # 去重
            
        except Exception as e:
            logger.warning(f"解析AI关键词失败，尝试简单提取: {e}")
            
            # 回退到简单的文本提取
            lines = ai_result.split('\n')
            for line in lines:
                if '关键词' in line or 'keyword' in line.lower():
                    # 提取引号或冒号后的内容
                    matches = re.findall(r'["\']([^"\']+)["\']', line)
                    keywords.extend(matches)
        
        # 过滤和清理关键词
        cleaned_keywords = []
        for kw in keywords:
            kw = kw.strip()
            if len(kw) >= 2 and len(kw) <= 10 and kw not in self.stop_words:
                cleaned_keywords.append(kw)
        
        return cleaned_keywords[:15]  # 限制数量
    
    def _score_keywords(self, keywords: List[str], content: str) -> Dict[str, float]:
        """为关键词打分"""
        scores = {}
        content_lower = content.lower()
        
        for keyword in keywords:
            score = 0.0
            keyword_lower = keyword.lower()
            
            # 1. 频率得分（0-40分）
            frequency = content_lower.count(keyword_lower)
            freq_score = min(frequency * 5, 40)
            score += freq_score
            
            # 2. 长度得分（0-20分）
            length_score = min(len(keyword) * 2, 20)
            score += length_score
            
            # 3. 位置得分（0-20分）
            if keyword_lower in content_lower[:100]:  # 出现在开头
                score += 20
            elif keyword_lower in content_lower[:200]:  # 出现在前200字符
                score += 10
            
            # 4. 类型得分（0-20分）
            type_score = self._get_keyword_type_score(keyword)
            score += type_score
            
            scores[keyword] = score
        
        return scores
    
    def _get_keyword_type_score(self, keyword: str) -> float:
        """根据关键词类型给分"""
        # 地理位置关键词得分较高
        if any(suffix in keyword for suffix in ['市', '省', '县', '区', '镇', '村']):
            return 20
        
        # 景点类关键词
        if any(suffix in keyword for suffix in ['景区', '公园', '山', '湖', '寺', '塔', '古镇']):
            return 18
        
        # 活动类关键词
        if any(word in keyword for word in ['游', '玩', '吃', '住', '行', '购', '娱']):
            return 15
        
        # 特色类关键词
        if any(word in keyword for word in ['特色', '美食', '文化', '历史', '自然']):
            return 12
        
        return 10  # 默认得分
    
    def _categorize_keywords(self, keywords: List[str]) -> Dict[str, List[str]]:
        """关键词分类"""
        categories = {category: [] for category in self.keyword_categories.keys()}
        categories['其他'] = []
        
        for keyword in keywords:
            categorized = False
            
            for category, patterns in self.keyword_categories.items():
                if any(pattern in keyword for pattern in patterns):
                    categories[category].append(keyword)
                    categorized = True
                    break
            
            if not categorized:
                # 基于关键词内容进行分类
                if any(suffix in keyword for suffix in ['市', '省', '县', '区', '镇', '村']):
                    categories['地理位置'].append(keyword)
                elif any(suffix in keyword for suffix in ['景区', '公园', '山', '湖', '寺', '塔']):
                    categories['景点类型'].append(keyword)
                elif any(word in keyword for word in ['游', '玩', '体验', '活动']):
                    categories['活动体验'].append(keyword)
                else:
                    categories['其他'].append(keyword)
        
        # 移除空分类
        return {k: v for k, v in categories.items() if v}
    
    def _generate_search_suggestions(self, keywords: List[str], content: str) -> List[str]:
        """生成搜索建议"""
        suggestions = []
        
        # 1. 单个关键词建议
        top_keywords = sorted(keywords, key=lambda x: len(x), reverse=True)[:10]
        suggestions.extend(top_keywords)
        
        # 2. 组合关键词建议
        location_keywords = [kw for kw in keywords if any(suffix in kw for suffix in ['市', '省', '景区', '古镇'])]
        activity_keywords = [kw for kw in keywords if any(word in kw for word in ['游', '玩', '美食', '攻略'])]
        
        # 地理位置 + 活动组合
        for loc in location_keywords[:3]:
            for act in activity_keywords[:2]:
                suggestions.append(f"{loc} {act}")
        
        # 3. 基于内容长度的建议
        if len(content) > 500:
            suggestions.append("详细攻略")
        if "美食" in content:
            suggestions.append("美食推荐")
        if "住宿" in content:
            suggestions.append("住宿攻略")
        
        # 去重并限制数量
        unique_suggestions = list(dict.fromkeys(suggestions))  # 保持顺序的去重
        return unique_suggestions[:20]
    
    def extract_search_keywords(self, topics: List[Dict[str, Any]]) -> List[str]:
        """
        从主题列表中提取搜索关键词
        
        Args:
            topics: 主题列表
            
        Returns:
            List[str]: 提取的关键词列表
        """
        keywords = []
        
        for topic in topics:
            # 从不同字段提取关键词
            for field in ['object', 'product', 'style', 'targetAudience']:
                if field in topic and topic[field]:
                    # 简单的关键词提取
                    text = str(topic[field])
                    words = self._extract_basic_keywords(text)
                    keywords.extend(words)
        
        # 去重并返回
        return list(set(keywords))
    
    def get_analyzer_stats(self) -> Dict[str, Any]:
        """获取分析器统计信息"""
        return {
            'supported_categories': list(self.keyword_categories.keys()),
            'stop_words_count': len(self.stop_words),
            'task_model_config': self.task_model_config,
            'ai_service_info': self.ai_service.get_model_info()
        } 