#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
多群聊协调系统
管理主辩论群、内部讨论群、策略会议群和Human干预群之间的协调
"""

import asyncio
import json
from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass, field
from enum import Enum
from datetime import datetime, timedelta
import logging

class ChatType(Enum):
    """群聊类型"""
    MAIN_DEBATE = "主辩论群"  # 公开辩论
    INTERNAL_DISCUSSION = "内部讨论群"  # 团队内部讨论
    STRATEGY_MEETING = "策略会议群"  # 策略制定
    HUMAN_INTERVENTION = "Human干预群"  # 人工干预
    OBSERVATION = "观察群"  # 观察和记录

class MessagePriority(Enum):
    """消息优先级"""
    LOW = 1
    NORMAL = 2
    HIGH = 3
    URGENT = 4
    CRITICAL = 5

class CoordinationAction(Enum):
    """协调动作"""
    ESCALATE = "升级"  # 升级到更高级别群聊
    DELEGATE = "委派"  # 委派到专门群聊
    BROADCAST = "广播"  # 广播到多个群聊
    FILTER = "过滤"  # 过滤不相关消息
    MERGE = "合并"  # 合并相关讨论
    ARCHIVE = "归档"  # 归档历史讨论

@dataclass
class ChatMessage:
    """群聊消息"""
    id: str
    chat_type: ChatType
    sender: str
    content: str
    timestamp: datetime
    priority: MessagePriority = MessagePriority.NORMAL
    tags: List[str] = field(default_factory=list)
    related_messages: List[str] = field(default_factory=list)
    metadata: Dict[str, Any] = field(default_factory=dict)

@dataclass
class ChatRoom:
    """群聊房间"""
    id: str
    chat_type: ChatType
    name: str
    description: str
    participants: List[str] = field(default_factory=list)
    moderators: List[str] = field(default_factory=list)
    is_active: bool = True
    created_at: datetime = field(default_factory=datetime.now)
    last_activity: datetime = field(default_factory=datetime.now)
    message_history: List[ChatMessage] = field(default_factory=list)
    settings: Dict[str, Any] = field(default_factory=dict)

@dataclass
class CoordinationRule:
    """协调规则"""
    id: str
    name: str
    description: str
    source_chat_types: List[ChatType]
    target_chat_types: List[ChatType]
    trigger_conditions: Dict[str, Any]
    action: CoordinationAction
    priority: int = 1
    is_active: bool = True
    created_at: datetime = field(default_factory=datetime.now)

class MultiChatCoordinator:
    """多群聊协调器"""
    
    def __init__(self):
        self.chat_rooms: Dict[str, ChatRoom] = {}
        self.coordination_rules: Dict[str, CoordinationRule] = {}
        self.message_queue: List[ChatMessage] = []
        self.event_handlers: Dict[str, List[Callable]] = {}
        self.logger = logging.getLogger(__name__)
        
        # 初始化默认群聊房间
        self._initialize_default_rooms()
        
        # 初始化默认协调规则
        self._initialize_default_rules()
    
    def _initialize_default_rooms(self):
        """初始化默认群聊房间"""
        default_rooms = [
            {
                "id": "main_debate",
                "chat_type": ChatType.MAIN_DEBATE,
                "name": "主辩论群",
                "description": "公开辩论的主要场所",
                "participants": ["正1", "正2", "正3", "正4", "反1", "反2", "反3", "反4"],
                "moderators": ["系统"],
                "settings": {
                    "max_message_length": 500,
                    "speaking_time_limit": 120,  # 秒
                    "auto_moderation": True
                }
            },
            {
                "id": "positive_internal",
                "chat_type": ChatType.INTERNAL_DISCUSSION,
                "name": "正方内部讨论群",
                "description": "正方团队内部策略讨论",
                "participants": ["正1", "正2", "正3", "正4"],
                "moderators": ["正1"],
                "settings": {
                    "privacy_level": "high",
                    "auto_archive": True
                }
            },
            {
                "id": "negative_internal",
                "chat_type": ChatType.INTERNAL_DISCUSSION,
                "name": "反方内部讨论群",
                "description": "反方团队内部策略讨论",
                "participants": ["反1", "反2", "反3", "反4"],
                "moderators": ["反1"],
                "settings": {
                    "privacy_level": "high",
                    "auto_archive": True
                }
            },
            {
                "id": "strategy_meeting",
                "chat_type": ChatType.STRATEGY_MEETING,
                "name": "策略会议群",
                "description": "高级策略制定和决策",
                "participants": ["正1", "反1", "系统"],
                "moderators": ["系统"],
                "settings": {
                    "meeting_mode": True,
                    "record_decisions": True
                }
            },
            {
                "id": "human_intervention",
                "chat_type": ChatType.HUMAN_INTERVENTION,
                "name": "Human干预群",
                "description": "人工干预和监督",
                "participants": ["Human", "系统"],
                "moderators": ["Human"],
                "settings": {
                    "alert_threshold": "high",
                    "auto_escalation": True
                }
            },
            {
                "id": "observation",
                "chat_type": ChatType.OBSERVATION,
                "name": "观察群",
                "description": "观察和记录所有活动",
                "participants": ["观察者", "记录员"],
                "moderators": ["系统"],
                "settings": {
                    "read_only": True,
                    "full_logging": True
                }
            }
        ]
        
        for room_config in default_rooms:
            room = ChatRoom(**room_config)
            self.chat_rooms[room.id] = room
    
    def _initialize_default_rules(self):
        """初始化默认协调规则"""
        default_rules = [
            {
                "id": "escalate_urgent_to_human",
                "name": "紧急情况升级到Human",
                "description": "当检测到紧急情况时，自动升级到Human干预群",
                "source_chat_types": [ChatType.MAIN_DEBATE, ChatType.INTERNAL_DISCUSSION],
                "target_chat_types": [ChatType.HUMAN_INTERVENTION],
                "trigger_conditions": {
                    "priority": MessagePriority.URGENT,
                    "keywords": ["紧急", "错误", "异常", "停止"]
                },
                "action": CoordinationAction.ESCALATE,
                "priority": 1
            },
            {
                "id": "strategy_to_internal",
                "name": "策略决策分发到内部群",
                "description": "将策略会议的决策分发到相关内部讨论群",
                "source_chat_types": [ChatType.STRATEGY_MEETING],
                "target_chat_types": [ChatType.INTERNAL_DISCUSSION],
                "trigger_conditions": {
                    "tags": ["决策", "策略", "指令"]
                },
                "action": CoordinationAction.BROADCAST,
                "priority": 2
            },
            {
                "id": "filter_noise",
                "name": "过滤噪音消息",
                "description": "过滤低质量或无关的消息",
                "source_chat_types": [ChatType.MAIN_DEBATE],
                "target_chat_types": [],
                "trigger_conditions": {
                    "priority": MessagePriority.LOW,
                    "content_length": {"max": 10}
                },
                "action": CoordinationAction.FILTER,
                "priority": 3
            },
            {
                "id": "archive_old_discussions",
                "name": "归档旧讨论",
                "description": "自动归档超过时间限制的讨论",
                "source_chat_types": [ChatType.INTERNAL_DISCUSSION],
                "target_chat_types": [ChatType.OBSERVATION],
                "trigger_conditions": {
                    "age_hours": 24,
                    "inactivity_hours": 2
                },
                "action": CoordinationAction.ARCHIVE,
                "priority": 4
            }
        ]
        
        for rule_config in default_rules:
            rule = CoordinationRule(**rule_config)
            self.coordination_rules[rule.id] = rule
    
    async def send_message(self, chat_id: str, sender: str, content: str, 
                          priority: MessagePriority = MessagePriority.NORMAL,
                          tags: List[str] = None) -> ChatMessage:
        """发送消息到指定群聊"""
        if chat_id not in self.chat_rooms:
            raise ValueError(f"群聊 {chat_id} 不存在")
        
        chat_room = self.chat_rooms[chat_id]
        
        # 检查发送者权限（系统用户有特殊权限）
        if sender != "系统" and sender not in chat_room.participants and sender not in chat_room.moderators:
            raise PermissionError(f"用户 {sender} 没有权限在群聊 {chat_id} 中发言")
        
        # 创建消息
        message = ChatMessage(
            id=f"{chat_id}_{datetime.now().timestamp()}",
            chat_type=chat_room.chat_type,
            sender=sender,
            content=content,
            timestamp=datetime.now(),
            priority=priority,
            tags=tags or []
        )
        
        # 添加到群聊历史
        chat_room.message_history.append(message)
        chat_room.last_activity = datetime.now()
        
        # 添加到消息队列进行协调处理
        self.message_queue.append(message)
        
        # 触发事件处理
        await self._trigger_event_handlers("message_sent", message)
        
        # 处理协调规则
        await self._process_coordination_rules(message)
        
        self.logger.info(f"消息已发送到 {chat_id}: {sender} - {content[:50]}...")
        
        return message
    
    async def _process_coordination_rules(self, message: ChatMessage):
        """处理协调规则"""
        for rule in self.coordination_rules.values():
            if not rule.is_active:
                continue
            
            # 检查源群聊类型
            if message.chat_type not in rule.source_chat_types:
                continue
            
            # 检查触发条件
            if await self._check_trigger_conditions(message, rule.trigger_conditions):
                await self._execute_coordination_action(message, rule)
    
    async def _check_trigger_conditions(self, message: ChatMessage, conditions: Dict[str, Any]) -> bool:
        """检查触发条件"""
        # 检查优先级
        if "priority" in conditions:
            if message.priority != conditions["priority"]:
                return False
        
        # 检查关键词
        if "keywords" in conditions:
            keywords = conditions["keywords"]
            if not any(keyword in message.content for keyword in keywords):
                return False
        
        # 检查标签
        if "tags" in conditions:
            required_tags = conditions["tags"]
            if not any(tag in message.tags for tag in required_tags):
                return False
        
        # 检查内容长度
        if "content_length" in conditions:
            length_rules = conditions["content_length"]
            content_length = len(message.content)
            
            if "min" in length_rules and content_length < length_rules["min"]:
                return False
            if "max" in length_rules and content_length > length_rules["max"]:
                return False
        
        # 检查消息年龄
        if "age_hours" in conditions:
            age_limit = timedelta(hours=conditions["age_hours"])
            if datetime.now() - message.timestamp > age_limit:
                return True
        
        return True
    
    async def _execute_coordination_action(self, message: ChatMessage, rule: CoordinationRule):
        """执行协调动作"""
        action = rule.action
        
        if action == CoordinationAction.ESCALATE:
            await self._escalate_message(message, rule.target_chat_types)
        
        elif action == CoordinationAction.BROADCAST:
            await self._broadcast_message(message, rule.target_chat_types)
        
        elif action == CoordinationAction.FILTER:
            await self._filter_message(message)
        
        elif action == CoordinationAction.ARCHIVE:
            await self._archive_message(message, rule.target_chat_types)
        
        elif action == CoordinationAction.DELEGATE:
            await self._delegate_message(message, rule.target_chat_types)
        
        elif action == CoordinationAction.MERGE:
            await self._merge_discussions(message)
        
        self.logger.info(f"执行协调动作 {action.value} for message {message.id}")
    
    async def _escalate_message(self, message: ChatMessage, target_chat_types: List[ChatType]):
        """升级消息到更高级别群聊"""
        for chat_type in target_chat_types:
            target_rooms = [room for room in self.chat_rooms.values() 
                          if room.chat_type == chat_type and room.is_active]
            
            for room in target_rooms:
                escalated_content = f"🚨 [升级消息] 来自 {message.chat_type.value}\n" \
                                  f"发送者: {message.sender}\n" \
                                  f"内容: {message.content}\n" \
                                  f"时间: {message.timestamp}"
                
                await self.send_message(
                    room.id, "系统", escalated_content, 
                    MessagePriority.URGENT, ["升级", "自动"]
                )
    
    async def _broadcast_message(self, message: ChatMessage, target_chat_types: List[ChatType]):
        """广播消息到多个群聊"""
        for chat_type in target_chat_types:
            target_rooms = [room for room in self.chat_rooms.values() 
                          if room.chat_type == chat_type and room.is_active]
            
            for room in target_rooms:
                broadcast_content = f"📢 [广播消息] 来自 {message.chat_type.value}\n" \
                                  f"{message.content}"
                
                await self.send_message(
                    room.id, "系统", broadcast_content, 
                    message.priority, message.tags + ["广播"]
                )
    
    async def _filter_message(self, message: ChatMessage):
        """过滤消息"""
        # 标记消息为已过滤
        message.metadata["filtered"] = True
        message.metadata["filter_reason"] = "低质量或无关内容"
        
        self.logger.info(f"消息 {message.id} 已被过滤")
    
    async def _archive_message(self, message: ChatMessage, target_chat_types: List[ChatType]):
        """归档消息"""
        for chat_type in target_chat_types:
            target_rooms = [room for room in self.chat_rooms.values() 
                          if room.chat_type == chat_type and room.is_active]
            
            for room in target_rooms:
                archive_content = f"📁 [归档消息] 来自 {message.chat_type.value}\n" \
                                f"原始内容: {message.content}\n" \
                                f"归档时间: {datetime.now()}"
                
                await self.send_message(
                    room.id, "系统", archive_content, 
                    MessagePriority.LOW, ["归档", "历史"]
                )
    
    async def _delegate_message(self, message: ChatMessage, target_chat_types: List[ChatType]):
        """委派消息到专门群聊"""
        # 类似于广播，但会移除原消息
        await self._broadcast_message(message, target_chat_types)
        
        # 标记原消息为已委派
        message.metadata["delegated"] = True
    
    async def _merge_discussions(self, message: ChatMessage):
        """合并相关讨论"""
        # 查找相关消息
        related_messages = self._find_related_messages(message)
        
        # 创建合并讨论摘要
        if related_messages:
            summary = self._create_discussion_summary(message, related_messages)
            
            # 发送摘要到策略会议群
            strategy_rooms = [room for room in self.chat_rooms.values() 
                            if room.chat_type == ChatType.STRATEGY_MEETING]
            
            for room in strategy_rooms:
                await self.send_message(
                    room.id, "系统", summary, 
                    MessagePriority.HIGH, ["合并", "摘要"]
                )
    
    def _find_related_messages(self, message: ChatMessage) -> List[ChatMessage]:
        """查找相关消息"""
        related = []
        
        # 简单的相关性检测：相同标签或关键词
        for room in self.chat_rooms.values():
            for msg in room.message_history[-10:]:  # 检查最近10条消息
                if msg.id != message.id:
                    # 检查标签重叠
                    if set(msg.tags) & set(message.tags):
                        related.append(msg)
                    
                    # 检查内容相似性（简单关键词匹配）
                    elif self._calculate_content_similarity(msg.content, message.content) > 0.3:
                        related.append(msg)
        
        return related
    
    def _calculate_content_similarity(self, content1: str, content2: str) -> float:
        """计算内容相似性"""
        words1 = set(content1.split())
        words2 = set(content2.split())
        
        if not words1 or not words2:
            return 0.0
        
        intersection = words1 & words2
        union = words1 | words2
        
        return len(intersection) / len(union)
    
    def _create_discussion_summary(self, main_message: ChatMessage, related_messages: List[ChatMessage]) -> str:
        """创建讨论摘要"""
        summary = f"📋 讨论摘要\n"
        summary += f"主要消息: {main_message.sender} - {main_message.content[:100]}...\n"
        summary += f"相关消息数量: {len(related_messages)}\n\n"
        
        summary += "相关讨论:\n"
        for i, msg in enumerate(related_messages[:5], 1):  # 最多显示5条
            summary += f"{i}. {msg.sender}: {msg.content[:50]}...\n"
        
        return summary
    
    async def _trigger_event_handlers(self, event_type: str, data: Any):
        """触发事件处理器"""
        if event_type in self.event_handlers:
            for handler in self.event_handlers[event_type]:
                try:
                    await handler(data)
                except Exception as e:
                    self.logger.error(f"事件处理器错误: {e}")
    
    def add_event_handler(self, event_type: str, handler: Callable):
        """添加事件处理器"""
        if event_type not in self.event_handlers:
            self.event_handlers[event_type] = []
        self.event_handlers[event_type].append(handler)
    
    async def handle_message(self, message_data: Dict[str, Any]) -> Dict[str, Any]:
        """处理消息（兼容性方法）"""
        try:
            chat_id = message_data.get("chat_id", "main_debate")
            speaker = message_data.get("speaker", "未知用户")
            content = message_data.get("content", "")
            priority = MessagePriority.NORMAL
            
            # 发送消息
            message = await self.send_message(chat_id, speaker, content, priority)
            
            return {
                "success": True,
                "message_id": message.id,
                "processed_at": datetime.now().isoformat()
            }
        except Exception as e:
            self.logger.error(f"处理消息失败: {e}")
            return {
                "success": False,
                "error": str(e),
                "processed_at": datetime.now().isoformat()
            }
    
    def get_routing_status(self) -> Dict[str, Any]:
        """获取路由状态（兼容性方法）"""
        return {
            "active_routes": len(self.coordination_rules),
            "message_queue_size": len(self.message_queue),
            "total_rooms": len(self.chat_rooms)
        }
    
    async def coordinate_response(self, message_data: Dict[str, Any], context: Dict[str, Any]) -> Dict[str, Any]:
        """协调响应（兼容性方法）"""
        try:
            # 基于上下文决定响应策略
            stage = context.get("stage", "起")
            topic = context.get("topic", "未知主题")
            
            # 模拟协调决策
            coordination_decision = {
                "recommended_action": "继续讨论",
                "target_chat": "main_debate",
                "priority": "normal",
                "reasoning": f"基于当前阶段({stage})和主题({topic})的协调决策"
            }
            
            return {
                "success": True,
                "coordination": coordination_decision,
                "timestamp": datetime.now().isoformat()
            }
        except Exception as e:
            return {
                "success": False,
                "error": str(e),
                "timestamp": datetime.now().isoformat()
            }
    
    def get_chat_status(self) -> Dict[str, Any]:
        """获取群聊状态"""
        status = {
            "total_rooms": len(self.chat_rooms),
            "active_rooms": len([r for r in self.chat_rooms.values() if r.is_active]),
            "total_messages": sum(len(r.message_history) for r in self.chat_rooms.values()),
            "pending_messages": len(self.message_queue),
            "coordination_rules": len(self.coordination_rules),
            "active_rules": len([r for r in self.coordination_rules.values() if r.is_active]),
            "rooms": {
                room_id: {
                    "name": room.name,
                    "type": room.chat_type.value,
                    "participants": len(room.participants),
                    "messages": len(room.message_history),
                    "last_activity": room.last_activity.isoformat(),
                    "is_active": room.is_active
                }
                for room_id, room in self.chat_rooms.items()
            }
        }
        
        return status
    
    def save_coordination_data(self, filename: str = "coordination_data.json"):
        """保存协调数据"""
        # 自定义JSON序列化函数
        def serialize_trigger_conditions(conditions):
            serialized = {}
            for key, value in conditions.items():
                if isinstance(value, MessagePriority):
                    serialized[key] = value.value
                else:
                    serialized[key] = value
            return serialized
        
        data = {
            "chat_rooms": {
                room_id: {
                    "id": room.id,
                    "chat_type": room.chat_type.value,
                    "name": room.name,
                    "description": room.description,
                    "participants": room.participants,
                    "moderators": room.moderators,
                    "is_active": room.is_active,
                    "created_at": room.created_at.isoformat(),
                    "last_activity": room.last_activity.isoformat(),
                    "settings": room.settings,
                    "message_count": len(room.message_history)
                }
                for room_id, room in self.chat_rooms.items()
            },
            "coordination_rules": {
                rule_id: {
                    "id": rule.id,
                    "name": rule.name,
                    "description": rule.description,
                    "source_chat_types": [ct.value for ct in rule.source_chat_types],
                    "target_chat_types": [ct.value for ct in rule.target_chat_types],
                    "trigger_conditions": serialize_trigger_conditions(rule.trigger_conditions),
                    "action": rule.action.value,
                    "priority": rule.priority,
                    "is_active": rule.is_active,
                    "created_at": rule.created_at.isoformat()
                }
                for rule_id, rule in self.coordination_rules.items()
            },
            "status": self.get_chat_status(),
            "export_time": datetime.now().isoformat()
        }
        
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
        
        self.logger.info(f"协调数据已保存到 {filename}")

# 使用示例
async def main():
    """使用示例"""
    coordinator = MultiChatCoordinator()
    
    # 发送一些测试消息
    await coordinator.send_message(
        "main_debate", "正1", 
        "我认为AI投资具有巨大的潜力和价值", 
        MessagePriority.NORMAL, ["观点", "AI"]
    )
    
    await coordinator.send_message(
        "main_debate", "反1", 
        "但是AI投资的风险也不容忽视", 
        MessagePriority.NORMAL, ["反驳", "风险"]
    )
    
    await coordinator.send_message(
        "positive_internal", "正2", 
        "我们需要准备更强有力的数据支持", 
        MessagePriority.HIGH, ["策略", "数据"]
    )
    
    # 模拟紧急情况
    await coordinator.send_message(
        "main_debate", "正3", 
        "系统出现异常，需要紧急处理", 
        MessagePriority.URGENT, ["紧急", "系统"]
    )
    
    # 显示状态
    status = coordinator.get_chat_status()
    print("\n📊 群聊协调系统状态:")
    print(f"总群聊数: {status['total_rooms']}")
    print(f"活跃群聊数: {status['active_rooms']}")
    print(f"总消息数: {status['total_messages']}")
    print(f"待处理消息: {status['pending_messages']}")
    
    print("\n📋 群聊详情:")
    for room_id, room_info in status['rooms'].items():
        print(f"  {room_info['name']} ({room_info['type']})")
        print(f"    参与者: {room_info['participants']} 人")
        print(f"    消息数: {room_info['messages']}")
        print(f"    最后活动: {room_info['last_activity']}")
        print()
    
    # 保存数据
    coordinator.save_coordination_data()

if __name__ == "__main__":
    asyncio.run(main())