#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
增强版优先级算法 v2.1.0
实现更复杂的权重计算和上下文分析能力
"""

import re
import math
from typing import Dict, List, Any, Optional, Tuple, Set
from dataclasses import dataclass, field
from datetime import datetime, timedelta
from enum import Enum
import json
from collections import defaultdict, deque
import hashlib
import statistics

class ArgumentType(Enum):
    """论点类型"""
    ATTACK = "攻击"
    DEFENSE = "防御"
    SUPPORT = "支持"
    REFUTE = "反驳"
    SUMMARY = "总结"
    QUESTION = "质疑"

class EmotionLevel(Enum):
    """情绪强度"""
    CALM = 1
    MILD = 2
    MODERATE = 3
    INTENSE = 4
    EXTREME = 5

@dataclass
class SpeechAnalysis:
    """发言分析结果"""
    argument_type: ArgumentType
    emotion_level: EmotionLevel
    logic_strength: float  # 0-1
    evidence_quality: float  # 0-1
    relevance_score: float  # 0-1
    urgency_score: float  # 0-1
    target_speakers: List[str]  # 针对的发言者
    keywords: List[str]
    sentiment_score: float  # -1 to 1

@dataclass
class SpeakerProfile:
    """发言者档案"""
    name: str
    team: str
    recent_speeches: List[Dict] = field(default_factory=list)
    total_speech_count: int = 0
    average_response_time: float = 30.0
    expertise_areas: List[str] = field(default_factory=list)
    debate_style: str = "analytical"  # "aggressive", "analytical", "diplomatic", "creative"
    current_energy: float = 1.0  # 0-1
    last_speech_time: Optional[datetime] = None
    # 新增字段
    historical_performance: Dict[str, float] = field(default_factory=dict)
    context_adaptability: float = 0.7  # 上下文适应能力
    argument_effectiveness: Dict[str, float] = field(default_factory=dict)  # 不同类型论点的有效性
    collaboration_score: float = 0.5  # 团队协作得分
    interruption_tendency: float = 0.3  # 打断倾向
    topic_expertise: Dict[str, float] = field(default_factory=dict)  # 话题专业度

class EnhancedPriorityAlgorithm:
    """增强版优先级算法"""
    
    def __init__(self):
        # 权重配置
        self.weights = {
            "rebuttal_urgency": 0.30,      # 反驳紧急性
            "argument_strength": 0.25,     # 论点强度
            "time_pressure": 0.20,         # 时间压力
            "audience_reaction": 0.15,      # 观众反应
            "strategy_need": 0.10          # 策略需要
        }
        
        # 情感关键词库
        self.emotion_keywords = {
            EmotionLevel.CALM: ["认为", "分析", "数据显示", "根据", "客观"],
            EmotionLevel.MILD: ["不同意", "质疑", "担心", "建议"],
            EmotionLevel.MODERATE: ["强烈", "明显", "严重", "重要"],
            EmotionLevel.INTENSE: ["绝对", "完全", "彻底", "必须"],
            EmotionLevel.EXTREME: ["荒谬", "愚蠢", "灾难", "危险"]
        }
        
        # 论点类型关键词
        self.argument_keywords = {
            ArgumentType.ATTACK: ["错误", "问题", "缺陷", "失败"],
            ArgumentType.DEFENSE: ["解释", "澄清", "说明", "回应"],
            ArgumentType.SUPPORT: ["支持", "赞同", "证实", "补充"],
            ArgumentType.REFUTE: ["反驳", "否定", "驳斥", "反对"],
            ArgumentType.SUMMARY: ["总结", "综上", "结论", "最后"],
            ArgumentType.QUESTION: ["为什么", "如何", "是否", "难道"]
        }
        
        # 发言者档案
        self.speaker_profiles: Dict[str, SpeakerProfile] = {}
        
        # 辩论历史分析
        self.debate_history: List[Dict] = []
        
        # 新增: 高级分析器组件
        self.context_analyzer = ContextAnalyzer()
        self.learning_system = LearningSystem()
        self.topic_drift_detector = TopicDriftDetector()
        self.emotion_dynamics = EmotionDynamicsModel()
        
    def analyze_speech(self, message: str, speaker: str, context: Dict) -> SpeechAnalysis:
        """分析发言内容"""
        # 检测论点类型
        argument_type = self._detect_argument_type(message)
        
        # 检测情绪强度
        emotion_level = self._detect_emotion_level(message)
        
        # 计算逻辑强度
        logic_strength = self._calculate_logic_strength(message)
        
        # 计算证据质量
        evidence_quality = self._calculate_evidence_quality(message)
        
        # 计算相关性分数
        relevance_score = self._calculate_relevance_score(message, context)
        
        # 计算紧急性分数
        urgency_score = self._calculate_urgency_score(message, context)
        
        # 识别目标发言者
        target_speakers = self._identify_target_speakers(message)
        
        # 提取关键词
        keywords = self._extract_keywords(message)
        
        # 计算情感分数
        sentiment_score = self._calculate_sentiment_score(message)
        
        return SpeechAnalysis(
            argument_type=argument_type,
            emotion_level=emotion_level,
            logic_strength=logic_strength,
            evidence_quality=evidence_quality,
            relevance_score=relevance_score,
            urgency_score=urgency_score,
            target_speakers=target_speakers,
            keywords=keywords,
            sentiment_score=sentiment_score
        )
    
    def calculate_speaker_priority(self, speaker: str, context: Dict, 
                                 recent_speeches: List[Dict]) -> float:
        """计算发言者优先级 - 增强版"""
        # 获取或创建发言者档案
        profile = self._get_or_create_speaker_profile(speaker)
        
        # 更新发言者档案
        self._update_speaker_profile(profile, recent_speeches)
        
        # === 基础分数计算 ===
        rebuttal_urgency = self._calculate_rebuttal_urgency(speaker, context, recent_speeches)
        argument_strength = self._calculate_argument_strength(speaker, profile)
        time_pressure = self._calculate_time_pressure(speaker, context)
        audience_reaction = self._calculate_audience_reaction(speaker, context)
        strategy_need = self._calculate_strategy_need(speaker, context, profile)
        
        # === 新增高级分析 ===
        # 1. 上下文流程分析
        flow_analysis = self.context_analyzer.analyze_debate_flow(recent_speeches)
        flow_bonus = self._calculate_flow_bonus(speaker, flow_analysis)
        
        # 2. 话题漂移检测
        if recent_speeches:
            last_speech = recent_speeches[-1].get("content", "")
            drift_analysis = self.topic_drift_detector.detect_drift(last_speech, context)
            drift_penalty = self._calculate_drift_penalty(speaker, drift_analysis)
        else:
            drift_penalty = 0.0
        
        # 3. 情绪动态分析
        emotion_analysis = self.emotion_dynamics.analyze_emotion_dynamics(recent_speeches)
        emotion_bonus = self._calculate_emotion_bonus(speaker, emotion_analysis, profile)
        
        # 4. 学习系统适应
        adaptation = self.learning_system.get_speaker_adaptation(speaker)
        adaptation_factor = adaptation.get("confidence", 0.5)
        
        # 5. 个性化权重调整
        personalized_weights = self._get_personalized_weights(speaker, profile, context)
        
        # === 加权计算总分 ===
        base_score = (
            rebuttal_urgency * personalized_weights["rebuttal_urgency"] +
            argument_strength * personalized_weights["argument_strength"] +
            time_pressure * personalized_weights["time_pressure"] +
            audience_reaction * personalized_weights["audience_reaction"] +
            strategy_need * personalized_weights["strategy_need"]
        )
        
        # 应用高级调整
        enhanced_score = base_score + flow_bonus - drift_penalty + emotion_bonus
        enhanced_score *= adaptation_factor
        
        # 应用传统修正因子
        final_score = self._apply_correction_factors(enhanced_score, speaker, profile, context)
        
        return min(max(final_score, 0.0), 1.0)  # 限制在0-1范围内
    
    def get_next_speaker(self, available_speakers: List[str], context: Dict, 
                        recent_speeches: List[Dict]) -> Tuple[str, float, Dict]:
        """获取下一个发言者"""
        speaker_scores = {}
        detailed_analysis = {}
        
        for speaker in available_speakers:
            score = self.calculate_speaker_priority(speaker, context, recent_speeches)
            speaker_scores[speaker] = score
            
            # 记录详细分析
            detailed_analysis[speaker] = {
                "priority_score": score,
                "profile": self.speaker_profiles.get(speaker),
                "analysis_timestamp": datetime.now().isoformat()
            }
        
        # 选择最高分发言者
        best_speaker = max(speaker_scores, key=speaker_scores.get)
        best_score = speaker_scores[best_speaker]
        
        return best_speaker, best_score, detailed_analysis
    
    def _detect_argument_type(self, message: str) -> ArgumentType:
        """检测论点类型"""
        message_lower = message.lower()
        type_scores = {}
        
        for arg_type, keywords in self.argument_keywords.items():
            score = sum(1 for keyword in keywords if keyword in message_lower)
            type_scores[arg_type] = score
        
        if not type_scores or max(type_scores.values()) == 0:
            return ArgumentType.SUPPORT  # 默认类型
        
        return max(type_scores, key=type_scores.get)
    
    def _detect_emotion_level(self, message: str) -> EmotionLevel:
        """检测情绪强度"""
        message_lower = message.lower()
        
        for emotion_level in reversed(list(EmotionLevel)):
            keywords = self.emotion_keywords.get(emotion_level, [])
            if any(keyword in message_lower for keyword in keywords):
                return emotion_level
        
        return EmotionLevel.CALM
    
    def _calculate_logic_strength(self, message: str) -> float:
        """计算逻辑强度"""
        logic_indicators = [
            "因为", "所以", "因此", "由于", "根据", "数据显示", 
            "研究表明", "事实上", "例如", "比如", "首先", "其次", "最后"
        ]
        
        message_lower = message.lower()
        logic_count = sum(1 for indicator in logic_indicators if indicator in message_lower)
        
        # 基于逻辑词汇密度计算
        word_count = len(message.split())
        if word_count == 0:
            return 0.0
        
        logic_density = logic_count / word_count
        return min(logic_density * 10, 1.0)  # 归一化到0-1
    
    def _calculate_evidence_quality(self, message: str) -> float:
        """计算证据质量"""
        evidence_indicators = [
            "数据", "统计", "研究", "报告", "调查", "实验", 
            "案例", "例子", "证据", "资料", "文献", "来源"
        ]
        
        message_lower = message.lower()
        evidence_count = sum(1 for indicator in evidence_indicators if indicator in message_lower)
        
        # 检查是否有具体数字
        number_pattern = r'\d+(?:\.\d+)?%?'
        numbers = re.findall(number_pattern, message)
        number_bonus = min(len(numbers) * 0.1, 0.3)
        
        base_score = min(evidence_count * 0.2, 0.7)
        return min(base_score + number_bonus, 1.0)
    
    def _calculate_relevance_score(self, message: str, context: Dict) -> float:
        """计算相关性分数"""
        # 简化实现：基于关键词匹配
        topic_keywords = context.get("topic_keywords", [])
        if not topic_keywords:
            return 0.5  # 默认中等相关性
        
        message_lower = message.lower()
        relevance_count = sum(1 for keyword in topic_keywords if keyword.lower() in message_lower)
        
        return min(relevance_count / len(topic_keywords), 1.0)
    
    def _calculate_urgency_score(self, message: str, context: Dict) -> float:
        """计算紧急性分数"""
        urgency_keywords = ["紧急", "立即", "马上", "现在", "重要", "关键", "危险"]
        
        message_lower = message.lower()
        urgency_count = sum(1 for keyword in urgency_keywords if keyword in message_lower)
        
        # 基于时间压力
        time_factor = context.get("time_remaining", 1.0)
        time_urgency = 1.0 - time_factor
        
        keyword_urgency = min(urgency_count * 0.3, 1.0)
        
        return min(keyword_urgency + time_urgency * 0.5, 1.0)
    
    def _identify_target_speakers(self, message: str) -> List[str]:
        """识别目标发言者"""
        # 简化实现：查找提及的发言者名称
        speaker_names = ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"]
        targets = []
        
        for name in speaker_names:
            if name in message:
                targets.append(name)
        
        return targets
    
    def _extract_keywords(self, message: str) -> List[str]:
        """提取关键词"""
        # 简化实现：提取长度大于2的词汇
        words = re.findall(r'\b\w{3,}\b', message)
        return list(set(words))[:10]  # 最多返回10个关键词
    
    def _calculate_sentiment_score(self, message: str) -> float:
        """计算情感分数"""
        positive_words = ["好", "优秀", "正确", "支持", "赞同", "成功", "有效"]
        negative_words = ["坏", "错误", "失败", "反对", "问题", "危险", "无效"]
        
        message_lower = message.lower()
        
        positive_count = sum(1 for word in positive_words if word in message_lower)
        negative_count = sum(1 for word in negative_words if word in message_lower)
        
        total_count = positive_count + negative_count
        if total_count == 0:
            return 0.0
        
        return (positive_count - negative_count) / total_count
    
    def _get_or_create_speaker_profile(self, speaker: str) -> SpeakerProfile:
        """获取或创建发言者档案"""
        if speaker not in self.speaker_profiles:
            self.speaker_profiles[speaker] = SpeakerProfile(
                name=speaker,
                team="positive" if "正" in speaker else "negative",
                recent_speeches=[],
                total_speech_count=0,
                average_response_time=3.0,
                expertise_areas=[],
                debate_style="analytical",
                current_energy=1.0
            )
        
        return self.speaker_profiles[speaker]
    
    def _update_speaker_profile(self, profile: SpeakerProfile, recent_speeches: List[Dict]):
        """更新发言者档案"""
        # 更新发言历史
        speaker_speeches = [s for s in recent_speeches if s.get("speaker") == profile.name]
        profile.recent_speeches = speaker_speeches[-5:]  # 保留最近5次发言
        profile.total_speech_count = len(speaker_speeches)
        
        # 更新能量水平（基于发言频率）
        if profile.last_speech_time:
            time_since_last = datetime.now() - profile.last_speech_time
            energy_recovery = min(time_since_last.seconds / 300, 0.5)  # 5分钟恢复50%
            profile.current_energy = min(profile.current_energy + energy_recovery, 1.0)
        
        profile.last_speech_time = datetime.now()
    
    def _calculate_rebuttal_urgency(self, speaker: str, context: Dict, 
                                  recent_speeches: List[Dict]) -> float:
        """计算反驳紧急性"""
        # 检查是否有针对该发言者团队的攻击
        team = "positive" if "正" in speaker else "negative"
        opposing_team = "negative" if team == "positive" else "positive"
        
        recent_attacks = 0
        for speech in recent_speeches[-5:]:  # 检查最近5次发言
            if speech.get("team") == opposing_team:
                analysis = speech.get("analysis", {})
                if analysis.get("argument_type") in [ArgumentType.ATTACK, ArgumentType.REFUTE]:
                    recent_attacks += 1
        
        # 基础紧急性 + 攻击响应紧急性
        # 为不同发言者生成不同的基础紧急性
        speaker_hash = hash(speaker) % 10  # 使用哈希值生成0-9的数字
        base_urgency = 0.1 + speaker_hash * 0.05  # 不同发言者有不同的基础紧急性
        attack_urgency = recent_attacks * 0.3
        
        return min(base_urgency + attack_urgency, 1.0)
    
    def _calculate_argument_strength(self, speaker: str, profile: SpeakerProfile) -> float:
        """计算论点强度"""
        # 基于历史表现
        if not profile.recent_speeches:
            # 为不同发言者提供不同的基础论点强度
            speaker_hash = hash(speaker) % 10  # 使用哈希值生成0-9的数字
            team_prefix = "正" if "正" in speaker else "反"
            
            # 基础强度根据发言者哈希值变化
            base_strength = 0.4 + speaker_hash * 0.06  # 0.4-1.0范围
            
            # 团队差异化
            team_factor = 1.05 if team_prefix == "正" else 0.95
            
            return min(base_strength * team_factor, 1.0)
        
        avg_logic = sum(s.get("analysis", {}).get("logic_strength", 0.5) 
                       for s in profile.recent_speeches) / len(profile.recent_speeches)
        avg_evidence = sum(s.get("analysis", {}).get("evidence_quality", 0.5) 
                          for s in profile.recent_speeches) / len(profile.recent_speeches)
        
        return (avg_logic + avg_evidence) / 2
    
    def _calculate_time_pressure(self, speaker: str, context: Dict) -> float:
        """计算时间压力"""
        time_remaining = context.get("time_remaining", 1.0)
        stage_progress = context.get("stage_progress", 0)
        max_progress = context.get("max_progress", 1)
        
        # 时间压力随剩余时间减少而增加
        time_pressure = 1.0 - time_remaining
        
        # 阶段进度压力
        progress_pressure = stage_progress / max_progress
        
        # 发言者个体差异
        speaker_hash = hash(speaker) % 10  # 使用哈希值生成0-9的数字
        speaker_factor = 0.8 + speaker_hash * 0.02  # 不同发言者有不同的时间敏感度
        
        base_pressure = (time_pressure + progress_pressure) / 2
        return min(base_pressure * speaker_factor, 1.0)
    
    def _calculate_audience_reaction(self, speaker: str, context: Dict) -> float:
        """计算观众反应"""
        # 简化实现：基于团队表现
        team = "positive" if "正" in speaker else "negative"
        team_score = context.get(f"{team}_team_score", 0.5)
        
        # 发言者个体魅力差异
        speaker_hash = hash(speaker) % 10  # 使用哈希值生成0-9的数字
        charisma_factor = 0.7 + speaker_hash * 0.03  # 不同发言者有不同的观众吸引力
        
        # 如果团队表现不佳，需要更多发言机会
        base_reaction = 1.0 - team_score
        return min(base_reaction * charisma_factor, 1.0)
    
    def _calculate_strategy_need(self, speaker: str, context: Dict, 
                               profile: SpeakerProfile) -> float:
        """计算策略需要"""
        # 基于发言者专长和当前需求
        current_stage = context.get("current_stage", "")
        
        # 为不同发言者提供差异化的策略需求
        speaker_hash = hash(speaker) % 10  # 使用哈希值生成0-9的数字
        team_prefix = "正" if "正" in speaker else "反"
        
        strategy_match = {
            "起": 0.8 if speaker_hash == 0 else 0.3 + speaker_hash * 0.05,  # 开场需要主力，但有差异
            "承": 0.4 + speaker_hash * 0.06,  # 承接阶段根据发言者哈希差异化
            "转": max(0.2, 1.0 - profile.current_energy + speaker_hash * 0.05),  # 自由辩论看能量和哈希
            "合": 0.9 if speaker_hash == 0 else 0.3 + speaker_hash * 0.05   # 总结需要主力，但有差异
        }
        
        base_score = strategy_match.get(current_stage, 0.5)
        
        # 添加团队差异化因子
        team_factor = 1.1 if team_prefix == "正" else 0.9
        
        return min(base_score * team_factor, 1.0)
    
    def _apply_correction_factors(self, base_score: float, speaker: str, 
                                profile: SpeakerProfile, context: Dict) -> float:
        """应用修正因子"""
        corrected_score = base_score
        
        # 能量修正
        corrected_score *= profile.current_energy
        
        # 发言频率修正（避免某人发言过多）
        recent_count = len([s for s in profile.recent_speeches 
                           if s.get("timestamp", "") > (datetime.now() - timedelta(minutes=5)).isoformat()])
        if recent_count > 2:
            corrected_score *= 0.7  # 降低优先级
        
        # 团队平衡修正
        team = "positive" if "正" in speaker else "negative"
        team_recent_count = context.get(f"{team}_recent_speeches", 0)
        opposing_recent_count = context.get(f"{'negative' if team == 'positive' else 'positive'}_recent_speeches", 0)
        
        if team_recent_count > opposing_recent_count + 2:
            corrected_score *= 0.8  # 平衡发言机会
        
        return corrected_score
    
    def calculate_priority(self, speaker: str, context: Dict, recent_speeches: List[Dict]) -> float:
        """计算发言者优先级（兼容性方法）"""
        return self.calculate_speaker_priority(speaker, context, recent_speeches)
    
    def get_algorithm_status(self) -> Dict[str, Any]:
        """获取算法状态"""
        return {
            "weights": self.weights,
            "speaker_count": len(self.speaker_profiles),
            "total_speeches_analyzed": len(self.debate_history),
            "algorithm_version": "2.1.0",
            "last_updated": datetime.now().isoformat()
        }
    
    def save_analysis_data(self, filename: str = "priority_analysis.json"):
        """保存分析数据"""
        data = {
            "algorithm_status": self.get_algorithm_status(),
            "speaker_profiles": {
                name: {
                    "name": profile.name,
                    "team": profile.team,
                    "total_speech_count": profile.total_speech_count,
                    "average_response_time": profile.average_response_time,
                    "expertise_areas": profile.expertise_areas,
                    "debate_style": profile.debate_style,
                    "current_energy": profile.current_energy,
                    "last_speech_time": profile.last_speech_time.isoformat() if profile.last_speech_time else None
                }
                for name, profile in self.speaker_profiles.items()
            },
            "debate_history": self.debate_history
        }
        
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        
        print(f"💾 优先级分析数据已保存到 {filename}")

def main():
    """测试增强版优先级算法"""
    print("🚀 增强版优先级算法测试")
    print("=" * 50)
    
    algorithm = EnhancedPriorityAlgorithm()
    
    # 模拟辩论上下文
    context = {
        "current_stage": "转",
        "stage_progress": 10,
        "max_progress": 36,
        "time_remaining": 0.6,
        "topic_keywords": ["人工智能", "投资", "风险", "收益"],
        "positive_team_score": 0.6,
        "negative_team_score": 0.4,
        "positive_recent_speeches": 3,
        "negative_recent_speeches": 2
    }
    
    # 模拟最近发言
    recent_speeches = [
        {
            "speaker": "正1",
            "team": "positive",
            "message": "根据数据显示，AI投资确实能带来显著收益",
            "timestamp": datetime.now().isoformat(),
            "analysis": {
                "argument_type": ArgumentType.SUPPORT,
                "logic_strength": 0.8,
                "evidence_quality": 0.7
            }
        },
        {
            "speaker": "反2",
            "team": "negative", 
            "message": "这种观点完全错误！AI投资风险巨大！",
            "timestamp": datetime.now().isoformat(),
            "analysis": {
                "argument_type": ArgumentType.ATTACK,
                "logic_strength": 0.3,
                "evidence_quality": 0.2
            }
        }
    ]
    
    available_speakers = ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"]
    
    # 计算下一个发言者
    next_speaker, score, analysis = algorithm.get_next_speaker(
        available_speakers, context, recent_speeches
    )
    
    print(f"\n🎯 推荐发言者: {next_speaker}")
    print(f"📊 优先级分数: {score:.3f}")
    print(f"\n📈 详细分析:")
    
    for speaker, data in analysis.items():
        print(f"  {speaker}: {data['priority_score']:.3f}")
    
    # 保存分析数据
    algorithm.save_analysis_data()
    
    print("\n✅ 增强版优先级算法测试完成！")

if __name__ == "__main__":
    main()


class ContextAnalyzer:
    """高级上下文分析器"""
    
    def __init__(self):
        self.context_memory = deque(maxlen=20)  # 保留最近20轮的上下文
        self.semantic_vectors = {}  # 语义向量缓存
        
    def analyze_debate_flow(self, recent_speeches: List[Dict]) -> Dict[str, Any]:
        """分析辩论流程"""
        if not recent_speeches:
            return {"flow_direction": "neutral", "momentum": 0.5, "tension": 0.3}
        
        # 分析辩论动量
        momentum = self._calculate_debate_momentum(recent_speeches)
        
        # 分析辩论紧张度
        tension = self._calculate_debate_tension(recent_speeches)
        
        # 分析流程方向
        flow_direction = self._analyze_flow_direction(recent_speeches)
        
        # 检测话题转换点
        topic_shifts = self._detect_topic_shifts(recent_speeches)
        
        return {
            "flow_direction": flow_direction,
            "momentum": momentum,
            "tension": tension,
            "topic_shifts": topic_shifts,
            "engagement_level": self._calculate_engagement_level(recent_speeches)
        }
    
    def _calculate_debate_momentum(self, speeches: List[Dict]) -> float:
        """计算辩论动量"""
        if len(speeches) < 2:
            return 0.5
        
        # 基于发言长度和情绪强度变化
        momentum_factors = []
        for i in range(1, len(speeches)):
            prev_speech = speeches[i-1]
            curr_speech = speeches[i]
            
            # 长度变化
            length_change = len(curr_speech.get("content", "")) - len(prev_speech.get("content", ""))
            length_factor = min(abs(length_change) / 100, 1.0)  # 归一化
            
            momentum_factors.append(length_factor)
        
        return statistics.mean(momentum_factors) if momentum_factors else 0.5
    
    def _calculate_debate_tension(self, speeches: List[Dict]) -> float:
        """计算辩论紧张度"""
        if not speeches:
            return 0.3
        
        tension_keywords = ["反驳", "错误", "质疑", "不同意", "反对", "驳斥"]
        
        tension_scores = []
        for speech in speeches[-5:]:  # 只看最近5轮
            content = speech.get("content", "")
            tension_count = sum(1 for keyword in tension_keywords if keyword in content)
            tension_scores.append(min(tension_count / 3, 1.0))
        
        return statistics.mean(tension_scores) if tension_scores else 0.3
    
    def _analyze_flow_direction(self, speeches: List[Dict]) -> str:
        """分析流程方向"""
        if len(speeches) < 3:
            return "neutral"
        
        recent_teams = [speech.get("team", "unknown") for speech in speeches[-3:]]
        
        positive_count = recent_teams.count("positive")
        negative_count = recent_teams.count("negative")
        
        if positive_count > negative_count:
            return "positive_dominant"
        elif negative_count > positive_count:
            return "negative_dominant"
        else:
            return "balanced"
    
    def _detect_topic_shifts(self, speeches: List[Dict]) -> List[Dict]:
        """检测话题转换点"""
        shifts = []
        if len(speeches) < 2:
            return shifts
        
        # 简化的话题转换检测
        for i in range(1, len(speeches)):
            prev_keywords = set(speeches[i-1].get("content", "").split()[:10])
            curr_keywords = set(speeches[i].get("content", "").split()[:10])
            
            # 计算关键词重叠度
            overlap = len(prev_keywords & curr_keywords) / max(len(prev_keywords | curr_keywords), 1)
            
            if overlap < 0.3:  # 重叠度低于30%认为是话题转换
                shifts.append({
                    "position": i,
                    "speaker": speeches[i].get("speaker"),
                    "shift_intensity": 1 - overlap
                })
        
        return shifts
    
    def _calculate_engagement_level(self, speeches: List[Dict]) -> float:
        """计算参与度"""
        if not speeches:
            return 0.5
        
        # 基于发言频率和长度
        total_length = sum(len(speech.get("content", "")) for speech in speeches)
        avg_length = total_length / len(speeches)
        
        # 归一化到0-1
        engagement = min(avg_length / 100, 1.0)
        return engagement


class LearningSystem:
    """学习系统，用于优化算法参数"""
    
    def __init__(self):
        self.performance_history = defaultdict(list)
        self.weight_adjustments = defaultdict(float)
        self.learning_rate = 0.05
        
    def record_performance(self, speaker: str, predicted_priority: float, 
                          actual_effectiveness: float, context: Dict):
        """记录表现数据"""
        self.performance_history[speaker].append({
            "predicted_priority": predicted_priority,
            "actual_effectiveness": actual_effectiveness,
            "context": context,
            "timestamp": datetime.now(),
            "error": abs(predicted_priority - actual_effectiveness)
        })
    
    def optimize_weights(self, algorithm_weights: Dict[str, float]) -> Dict[str, float]:
        """优化权重参数"""
        if not self.performance_history:
            return algorithm_weights
        
        # 计算每个组件的平均误差
        component_errors = {}
        for component in algorithm_weights.keys():
            errors = []
            for speaker_data in self.performance_history.values():
                for record in speaker_data[-10:]:  # 只看最近10次
                    errors.append(record["error"])
            
            if errors:
                component_errors[component] = statistics.mean(errors)
        
        # 根据误差调整权重
        optimized_weights = algorithm_weights.copy()
        for component, error in component_errors.items():
            if error > 0.3:  # 误差过大，降低权重
                adjustment = -self.learning_rate * error
            else:  # 误差合理，略微增加权重
                adjustment = self.learning_rate * (0.3 - error)
            
            optimized_weights[component] = max(0.05, min(0.5, 
                optimized_weights[component] + adjustment))
        
        # 归一化权重
        total_weight = sum(optimized_weights.values())
        if total_weight > 0:
            optimized_weights = {k: v/total_weight for k, v in optimized_weights.items()}
        
        return optimized_weights
    
    def get_speaker_adaptation(self, speaker: str) -> Dict[str, float]:
        """获取发言者特定的适应参数"""
        if speaker not in self.performance_history:
            return {"confidence": 0.5, "adaptability": 0.5}
        
        recent_records = self.performance_history[speaker][-5:]
        if not recent_records:
            return {"confidence": 0.5, "adaptability": 0.5}
        
        # 计算准确性趋势
        errors = [record["error"] for record in recent_records]
        avg_error = statistics.mean(errors)
        
        confidence = max(0.1, 1.0 - avg_error)
        adaptability = min(1.0, 0.3 + (1.0 - statistics.stdev(errors)) if len(errors) > 1 else 0.7)
        
        return {"confidence": confidence, "adaptability": adaptability}


class TopicDriftDetector:
    """话题漂移检测器"""
    
    def __init__(self):
        self.topic_history = deque(maxlen=50)
        self.keywords_cache = {}
        
    def detect_drift(self, current_speech: str, context: Dict) -> Dict[str, Any]:
        """检测话题漂移"""
        current_keywords = self._extract_topic_keywords(current_speech)
        
        if not self.topic_history:
            self.topic_history.append(current_keywords)
            return {"drift_detected": False, "drift_intensity": 0.0}
        
        # 计算与历史话题的相似度
        similarities = []
        for historical_keywords in list(self.topic_history)[-5:]:  # 最近5轮
            similarity = self._calculate_keyword_similarity(current_keywords, historical_keywords)
            similarities.append(similarity)
        
        avg_similarity = statistics.mean(similarities)
        drift_intensity = 1.0 - avg_similarity
        
        # 更新历史
        self.topic_history.append(current_keywords)
        
        return {
            "drift_detected": drift_intensity > 0.4,  # 阈值40%
            "drift_intensity": drift_intensity,
            "current_keywords": current_keywords,
            "recommendation": self._get_drift_recommendation(float(drift_intensity))
        }
    
    def _extract_topic_keywords(self, text: str) -> Set[str]:
        """提取话题关键词"""
        # 简化的关键词提取
        words = re.findall(r'\b\w{2,}\b', text.lower())
        
        # 过滤停用词
        stop_words = {"的", "了", "在", "是", "我", "你", "他", "她", "我们", "这", "那"}
        keywords = {word for word in words if word not in stop_words and len(word) > 1}
        
        return keywords
    
    def _calculate_keyword_similarity(self, keywords1: Set[str], keywords2: Set[str]) -> float:
        """计算关键词相似度"""
        if not keywords1 or not keywords2:
            return 0.0
        
        intersection = keywords1 & keywords2
        union = keywords1 | keywords2
        
        return len(intersection) / len(union) if union else 0.0
    
    def _get_drift_recommendation(self, drift_intensity: float) -> str:
        """获取漂移建议"""
        if drift_intensity > 0.7:
            return "major_topic_shift_detected"
        elif drift_intensity > 0.4:
            return "moderate_drift_detected"
        else:
            return "topic_stable"


class EmotionDynamicsModel:
    """情绪动力学模型"""
    
    def __init__(self):
        self.emotion_history = deque(maxlen=30)
        self.speaker_emotion_profiles = defaultdict(list)
        
    def analyze_emotion_dynamics(self, recent_speeches: List[Dict]) -> Dict[str, Any]:
        """分析情绪动态"""
        if not recent_speeches:
            return {"overall_trend": "neutral", "intensity_change": 0.0}
        
        # 提取情绪序列
        emotion_sequence = []
        for speech in recent_speeches:
            emotion_score = self._calculate_emotion_score(speech.get("content", ""))
            emotion_sequence.append(emotion_score)
            
            # 更新发言者情绪档案
            speaker = speech.get("speaker")
            if speaker:
                self.speaker_emotion_profiles[speaker].append(emotion_score)
        
        if len(emotion_sequence) < 2:
            return {"overall_trend": "neutral", "intensity_change": 0.0}
        
        # 计算情绪趋势
        trend = self._calculate_emotion_trend(emotion_sequence)
        
        # 计算强度变化
        intensity_change = emotion_sequence[-1] - emotion_sequence[0]
        
        # 检测情绪拐点
        turning_points = self._detect_emotion_turning_points(emotion_sequence)
        
        return {
            "overall_trend": trend,
            "intensity_change": intensity_change,
            "current_intensity": emotion_sequence[-1],
            "turning_points": turning_points,
            "volatility": statistics.stdev(emotion_sequence) if len(emotion_sequence) > 1 else 0.0
        }
    
    def _calculate_emotion_score(self, text: str) -> float:
        """计算情绪分数"""
        positive_words = ["好", "棒", "优秀", "正确", "支持", "赞同", "有效"]
        negative_words = ["坏", "错", "糟糕", "反对", "质疑", "问题", "失败"]
        intense_words = ["强烈", "坚决", "绝对", "完全", "彻底"]
        
        text_lower = text.lower()
        
        positive_count = sum(1 for word in positive_words if word in text_lower)
        negative_count = sum(1 for word in negative_words if word in text_lower)
        intense_count = sum(1 for word in intense_words if word in text_lower)
        
        base_emotion = (positive_count - negative_count) / max(len(text.split()), 1)
        intensity_multiplier = 1 + (intense_count * 0.5)
        
        return base_emotion * intensity_multiplier
    
    def _calculate_emotion_trend(self, sequence: List[float]) -> str:
        """计算情绪趋势"""
        if len(sequence) < 2:
            return "neutral"
        
        # 简单线性回归估算
        if len(sequence) < 2:
            return 0.0
        
        # 计算斜率
        n = len(sequence)
        sum_x = sum(range(n))
        sum_y = sum(sequence)
        sum_xy = sum(i * sequence[i] for i in range(n))
        sum_x2 = sum(i * i for i in range(n))
        
        slope = (n * sum_xy - sum_x * sum_y) / (n * sum_x2 - sum_x * sum_x)
        
        if slope > 0.1:
            return "escalating"
        elif slope < -0.1:
            return "de_escalating"
        else:
            return "stable"
    
    def _detect_emotion_turning_points(self, sequence: List[float]) -> List[int]:
        """检测情绪拐点"""
        if len(sequence) < 3:
            return []
        
        turning_points = []
        for i in range(1, len(sequence) - 1):
            prev_val = sequence[i-1]
            curr_val = sequence[i]
            next_val = sequence[i+1]
            
            # 检测峰值和谷值
            if (curr_val > prev_val and curr_val > next_val) or \
               (curr_val < prev_val and curr_val < next_val):
                turning_points.append(i)
        
        return turning_points