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

"""
Content Integrator
内容整合器 - 重构版本，将多个文档的内容进行整合和分析
"""

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

from .text_extractor import ExtractedDocument
from ..config import DocumentProcessingConfig
from ..exceptions import DocumentProcessingError

logger = logging.getLogger(__name__)


@dataclass
class IntegratedContent:
    """整合后的内容"""
    documents: List[ExtractedDocument]
    document_count: int
    total_content_length: int
    document_types: Dict[str, int]
    combined_content: str
    content_summary: str
    key_topics: List[str]
    integration_metadata: Dict[str, Any]
    integrated_at: datetime
    
    def __post_init__(self):
        """初始化后处理"""
        if not self.integrated_at:
            self.integrated_at = datetime.now()
        
        if not self.document_types:
            self.document_types = {}
            for doc in self.documents:
                file_type = doc.file_type
                self.document_types[file_type] = self.document_types.get(file_type, 0) + 1
    
    def to_dict(self) -> Dict[str, Any]:
        """转换为字典格式"""
        return {
            'document_count': self.document_count,
            'total_content_length': self.total_content_length,
            'document_types': self.document_types,
            'combined_content': self.combined_content,
            'content_summary': self.content_summary,
            'key_topics': self.key_topics,
            'integration_metadata': self.integration_metadata,
            'integrated_at': self.integrated_at.isoformat(),
            'documents': [doc.get_summary() for doc in self.documents]
        }
    
    def get_statistics(self) -> Dict[str, Any]:
        """获取内容统计信息"""
        total_words = sum(len(doc.content.split()) for doc in self.documents)
        successful_docs = [doc for doc in self.documents if not doc.error_info]
        
        return {
            'total_documents': self.document_count,
            'successful_extractions': len(successful_docs),
            'failed_extractions': self.document_count - len(successful_docs),
            'total_words': total_words,
            'total_content_length': self.total_content_length,
            'average_content_length': self.total_content_length / max(1, len(successful_docs)),
            'document_types': self.document_types,
            'key_topics_count': len(self.key_topics)
        }


class ContentIntegrator:
    """
    内容整合器 - 重构版本
    负责整合多个文档的信息，提取关键内容和主题
    """
    
    def __init__(self, config: DocumentProcessingConfig):
        """
        初始化内容整合器
        
        Args:
            config: 文档处理配置
        """
        self.config = config
        
        # 停用词列表（中文）
        self.stop_words = {
            '的', '了', '是', '在', '有', '和', '就', '不', '人', '都', '一', '个', '上', '也', '很', '到', '说', '要', '去', 
            '你', '会', '着', '没', '看', '好', '自己', '这', '那', '来', '可以', '时候', '我', '他', '她', '它', '们',
            '之', '与', '及', '或', '但', '而', '因为', '所以', '如果', '虽然', '然而', '因此', '于是', '总之',
            '的话', '这样', '那样', '这里', '那里', '现在', '以前', '以后', '当时', '刚才', '马上', '立即'
        }
        
        logger.info("内容整合器初始化完成")
    
    def integrate_documents(self, documents: List[ExtractedDocument]) -> IntegratedContent:
        """
        整合多个文档
        
        Args:
            documents: 提取的文档列表
            
        Returns:
            IntegratedContent: 整合后的内容
            
        Raises:
            DocumentProcessingError: 整合失败时抛出
        """
        if not documents:
            return IntegratedContent(
                documents=[],
                document_count=0,
                total_content_length=0,
                document_types={},
                combined_content="",
                content_summary="没有可处理的文档",
                key_topics=[],
                integration_metadata={'integration_method': 'empty'},
                integrated_at=datetime.now()
            )
        
        try:
            logger.info(f"开始整合 {len(documents)} 个文档")
            
            # 过滤成功提取的文档
            successful_docs = [doc for doc in documents if doc.content and not doc.error_info]
            
            if not successful_docs:
                logger.warning("没有成功提取的文档内容")
                return self._create_empty_integration(documents, "所有文档提取失败")
            
            # 合并内容
            combined_content = self._combine_content(successful_docs)
            
            # 生成内容摘要
            content_summary = self._generate_summary(combined_content, successful_docs)
            
            # 提取关键主题
            key_topics = self._extract_key_topics(combined_content)
            
            # 收集统计信息
            integration_metadata = self._collect_metadata(documents, successful_docs)
            
            # 计算总内容长度
            total_content_length = sum(len(doc.content) for doc in successful_docs)
            
            integrated_content = IntegratedContent(
                documents=documents,
                document_count=len(documents),
                total_content_length=total_content_length,
                document_types=self._count_document_types(documents),
                combined_content=combined_content,
                content_summary=content_summary,
                key_topics=key_topics,
                integration_metadata=integration_metadata,
                integrated_at=datetime.now()
            )
            
            logger.info(f"文档整合完成，合并内容长度: {len(combined_content)}")
            return integrated_content
            
        except Exception as e:
            error_msg = f"文档整合失败: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise DocumentProcessingError(error_msg)
    
    def _combine_content(self, documents: List[ExtractedDocument]) -> str:
        """合并文档内容"""
        if not documents:
            return ""
        
        combined_parts = []
        
        for i, doc in enumerate(documents):
            if doc.content.strip():
                # 添加文档分隔符
                if i > 0:
                    combined_parts.append(f"\n{'='*50}\n")
                
                # 添加文档头信息
                combined_parts.append(f"文档: {doc.filename} ({doc.file_type})\n")
                if doc.page_count:
                    combined_parts.append(f"页数: {doc.page_count}\n")
                combined_parts.append("-" * 30 + "\n")
                
                # 添加文档内容
                content = doc.content.strip()
                
                # 应用内容长度限制
                if self.config.max_content_length > 0 and len(content) > self.config.max_content_length:
                    content = content[:self.config.max_content_length] + "\n[内容已截断...]"
                
                combined_parts.append(content)
                combined_parts.append("\n")
        
        return "".join(combined_parts)
    
    def _generate_summary(self, combined_content: str, documents: List[ExtractedDocument]) -> str:
        """生成内容摘要"""
        if not combined_content.strip():
            return "无内容可摘要"
        
        summary_parts = []
        
        # 基本统计
        word_count = len(combined_content.split())
        char_count = len(combined_content)
        
        summary_parts.append(f"文档摘要:")
        summary_parts.append(f"- 成功处理文档数: {len(documents)}")
        summary_parts.append(f"- 总字符数: {char_count:,}")
        summary_parts.append(f"- 总词数: {word_count:,}")
        
        # 文档类型统计
        doc_types = Counter(doc.file_type for doc in documents)
        summary_parts.append(f"- 文档类型分布: {dict(doc_types)}")
        
        # 内容长度分析
        content_lengths = [len(doc.content) for doc in documents if doc.content]
        if content_lengths:
            avg_length = sum(content_lengths) / len(content_lengths)
            summary_parts.append(f"- 平均文档长度: {avg_length:.0f} 字符")
        
        # 提取前几个段落作为内容预览
        paragraphs = [p.strip() for p in combined_content.split('\n') if p.strip()]
        preview_paragraphs = []
        
        for para in paragraphs[:5]:  # 最多取前5个段落
            if len(para) > 10 and not para.startswith('-') and not para.startswith('='):
                preview_paragraphs.append(para[:100] + "..." if len(para) > 100 else para)
        
        if preview_paragraphs:
            summary_parts.append("\n内容预览:")
            for i, para in enumerate(preview_paragraphs, 1):
                summary_parts.append(f"{i}. {para}")
        
        return "\n".join(summary_parts)
    
    def _extract_key_topics(self, content: str) -> List[str]:
        """提取关键主题"""
        if not content.strip():
            return []
        
        try:
            # 文本预处理
            text = self._preprocess_text(content)
            
            # 提取词频
            word_freq = self._calculate_word_frequency(text)
            
            # 筛选关键词
            keywords = self._filter_keywords(word_freq)
            
            # 主题聚类（简单版本）
            topics = self._cluster_topics(keywords, content)
            
            return topics[:self.config.max_topics]
            
        except Exception as e:
            logger.warning(f"关键主题提取失败: {e}")
            return []
    
    def _preprocess_text(self, text: str) -> str:
        """文本预处理"""
        # 移除特殊字符和数字
        text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z\s]', ' ', text)
        
        # 移除多余空白
        text = re.sub(r'\s+', ' ', text).strip()
        
        return text
    
    def _calculate_word_frequency(self, text: str) -> Dict[str, int]:
        """计算词频"""
        words = text.split()
        word_freq = Counter()
        
        for word in words:
            word = word.strip().lower()
            
            # 过滤短词和停用词
            if len(word) >= 2 and word not in self.stop_words:
                word_freq[word] += 1
        
        return dict(word_freq)
    
    def _filter_keywords(self, word_freq: Dict[str, int]) -> List[tuple]:
        """筛选关键词"""
        # 按频率排序
        sorted_words = sorted(word_freq.items(), key=lambda x: x[1], reverse=True)
        
        # 取前N个高频词作为关键词
        keywords = []
        for word, freq in sorted_words[:50]:  # 最多50个关键词
            if freq >= 2:  # 至少出现2次
                keywords.append((word, freq))
        
        return keywords
    
    def _cluster_topics(self, keywords: List[tuple], content: str) -> List[str]:
        """简单的主题聚类"""
        if not keywords:
            return []
        
        topics = []
        
        # 基于关键词生成主题
        keyword_words = [kw[0] for kw in keywords[:20]]
        
        # 预定义主题模式
        topic_patterns = {
            '景区介绍': ['景区', '景点', '景观', '风景', '旅游', '游览', '参观', '观光'],
            '门票价格': ['门票', '价格', '费用', '收费', '票价', '优惠', '折扣'],
            '开放时间': ['时间', '开放', '营业', '闭园', '时段', '时刻'],
            '交通指南': ['交通', '路线', '公交', '地铁', '自驾', '停车', '导航'],
            '服务设施': ['服务', '设施', '餐厅', '厕所', '休息', '购物', '商店'],
            '注意事项': ['注意', '提醒', '禁止', '安全', '建议', '须知'],
            '活动体验': ['活动', '体验', '表演', '娱乐', '项目', '节目']
        }
        
        for topic_name, patterns in topic_patterns.items():
            matches = 0
            for keyword in keyword_words:
                for pattern in patterns:
                    if pattern in keyword or keyword in pattern:
                        matches += 1
                        break
            
            if matches >= 2:  # 至少匹配2个模式
                topics.append(topic_name)
        
        # 如果没有匹配的预定义主题，使用高频关键词
        if not topics:
            topics = [kw[0] for kw in keywords[:5]]
        
        return topics
    
    def _count_document_types(self, documents: List[ExtractedDocument]) -> Dict[str, int]:
        """统计文档类型"""
        type_counts = Counter()
        for doc in documents:
            type_counts[doc.file_type] += 1
        return dict(type_counts)
    
    def _collect_metadata(self, all_documents: List[ExtractedDocument], successful_docs: List[ExtractedDocument]) -> Dict[str, Any]:
        """收集整合元数据"""
        total_file_size = sum(doc.file_size for doc in all_documents)
        extraction_methods = Counter(doc.extraction_method for doc in successful_docs if doc.extraction_method)
        
        return {
            'integration_method': 'content_integrator_v2',
            'total_documents': len(all_documents),
            'successful_extractions': len(successful_docs),
            'failed_extractions': len(all_documents) - len(successful_docs),
            'total_file_size': total_file_size,
            'extraction_methods_used': dict(extraction_methods),
            'processing_timestamp': datetime.now().isoformat(),
            'content_integration_enabled': self.config.enable_content_integration,
            'max_content_length': self.config.max_content_length,
            'max_topics': self.config.max_topics
        }
    
    def _create_empty_integration(self, documents: List[ExtractedDocument], reason: str) -> IntegratedContent:
        """创建空的整合结果"""
        return IntegratedContent(
            documents=documents,
            document_count=len(documents),
            total_content_length=0,
            document_types=self._count_document_types(documents),
            combined_content="",
            content_summary=f"整合失败: {reason}",
            key_topics=[],
            integration_metadata={'integration_method': 'empty', 'failure_reason': reason},
            integrated_at=datetime.now()
        )
    
    def analyze_content_overlap(self, documents: List[ExtractedDocument]) -> Dict[str, Any]:
        """分析文档内容重叠情况"""
        if len(documents) < 2:
            return {'overlap_analysis': '需要至少2个文档进行重叠分析'}
        
        # 简单的重叠分析
        doc_words = []
        for doc in documents:
            if doc.content and not doc.error_info:
                words = set(self._preprocess_text(doc.content).split())
                doc_words.append((doc.filename, words))
        
        if len(doc_words) < 2:
            return {'overlap_analysis': '没有足够的有效文档内容进行分析'}
        
        overlap_results = {}
        
        for i in range(len(doc_words)):
            for j in range(i + 1, len(doc_words)):
                doc1_name, words1 = doc_words[i]
                doc2_name, words2 = doc_words[j]
                
                common_words = words1.intersection(words2)
                total_words = len(words1.union(words2))
                
                if total_words > 0:
                    overlap_ratio = len(common_words) / total_words
                    overlap_results[f"{doc1_name} vs {doc2_name}"] = {
                        'common_words_count': len(common_words),
                        'overlap_ratio': round(overlap_ratio, 3),
                        'common_words_sample': list(common_words)[:10]
                    }
        
        return {
            'overlap_analysis': overlap_results,
            'total_comparisons': len(overlap_results)
        }
    
    def get_integration_stats(self) -> Dict[str, Any]:
        """获取整合器统计信息"""
        return {
            'max_content_length': self.config.max_content_length,
            'max_topics': self.config.max_topics,
            'enable_content_integration': self.config.enable_content_integration,
            'stop_words_count': len(self.stop_words),
            'supported_analysis': [
                'content_combination',
                'summary_generation', 
                'key_topic_extraction',
                'content_overlap_analysis',
                'document_type_statistics'
            ]
        } 