"""
导航网格编辑器
提供可视化编辑导航网格的功能
"""

from typing import List, Optional, Dict, Any
from panda3d.core import Vec3, Point3, KeyboardButton, MouseWatcher

class NavMeshEditor:
    """
    导航网格编辑器
    提供可视化编辑导航网格的功能
    """
    
    def __init__(self, world, navmesh_manager):
        """
        初始化导航网格编辑器
        
        Args:
            world: 3D世界对象
            navmesh_manager: 导航网格管理器
        """
        self.world = world
        self.navmesh_manager = navmesh_manager
        self.visible = False
        
        # 编辑器状态
        self.edit_mode = False
        self.selected_polygon = None
        self.edit_tool = "select"  # select, add, delete, paint
        self.brush_size = 1.0
        
        # 编辑器GUI元素
        self.gui_elements = []
        self.tool_buttons = {}
        self.property_controls = {}
        
        # 鼠标交互
        self.mouse_watcher = None
        self.last_mouse_pos = None
        
        # 编辑历史（用于撤销/重做）
        self.edit_history = []
        self.history_index = -1
        self.max_history_size = 50
        
        print("✓ 导航网格编辑器初始化完成")
        
    def toggle_visibility(self):
        """切换编辑器可见性"""
        if self.visible:
            self.hide()
        else:
            self.show()
            
    def show(self):
        """显示编辑器"""
        if self.visible:
            return
            
        self.visible = True
        self._create_editor_gui()
        print("✓ 导航网格编辑器已显示")
        
    def hide(self):
        """隐藏编辑器"""
        if not self.visible:
            return
            
        self.visible = False
        self._cleanup_editor_gui()
        print("✓ 导航网格编辑器已隐藏")
        
    def _create_editor_gui(self):
        """创建编辑器GUI"""
        try:
            if not hasattr(self.world, 'gui_manager') or not self.world.gui_manager:
                print("⚠ GUI管理器不可用，无法创建编辑器界面")
                return
                
            gui_manager = self.world.gui_manager
            
            # 创建编辑器面板标题
            panel = gui_manager.createGUIButton(
                pos=(0.7, 0, 0.95), 
                text="导航网格编辑器", 
                size=0.06
            )
            self.gui_elements.append(panel)
            
            # 创建工具按钮
            tools = [
                ("选择", "select"),
                ("添加", "add"),
                ("删除", "delete"),
                ("绘制", "paint")
            ]
            
            for i, (name, tool) in enumerate(tools):
                button = gui_manager.createGUIButton(
                    pos=(0.7, 0, 0.88 - i * 0.06), 
                    text=name, 
                    size=0.04
                )
                self.gui_elements.append(button)
                self.tool_buttons[tool] = button
                self.world.accept(f"navmesh_tool_{tool}", 
                                lambda t=tool: self.set_edit_tool(t))
                
            # 创建编辑功能按钮
            functions = [
                ("生成网格", self.generate_navmesh),
                ("加载网格", self.load_navmesh),
                ("保存网格", self.save_navmesh),
                ("清除网格", self.clear_navmesh),
                ("撤销", self.undo),
                ("重做", self.redo)
            ]
            
            for i, (name, callback) in enumerate(functions):
                button = gui_manager.createGUIButton(
                    pos=(0.82, 0, 0.88 - i * 0.06), 
                    text=name, 
                    size=0.04
                )
                self.gui_elements.append(button)
                self.world.accept(f"navmesh_func_{name}", callback)
                
            # 创建属性控制
            self._create_property_controls()
            
            # 显示网格
            self.navmesh_manager.toggle_visibility()
            
        except Exception as e:
            print(f"⚠ 编辑器GUI创建失败: {e}")
            
    def _create_property_controls(self):
        """创建属性控制面板"""
        if not hasattr(self.world, 'gui_manager') or not self.world.gui_manager:
            return
            
        gui_manager = self.world.gui_manager
        
        # 网格属性
        properties = [
            ("网格大小", "cell_size", 0.1, 2.0, 0.1),
            ("网格高度", "cell_height", 0.1, 1.0, 0.1),
            ("代理高度", "agent_height", 0.5, 3.0, 0.1),
            ("代理半径", "agent_radius", 0.1, 2.0, 0.1),
            ("最大坡度", "max_slope", 0.0, 89.0, 1.0),
            ("笔刷大小", "brush_size", 0.1, 5.0, 0.1)
        ]
        
        for i, (name, prop, min_val, max_val, step) in enumerate(properties):
            y_pos = 0.5 - i * 0.055
            
            # 属性标签
            label = gui_manager.createGUIButton(
                pos=(0.75, 0, y_pos), 
                text=f"{name}:", 
                size=0.03
            )
            self.gui_elements.append(label)
            
            # 属性值显示
            value_label = gui_manager.createGUIButton(
                pos=(0.88, 0, y_pos), 
                text=f"{getattr(self.navmesh_manager, prop, 0.0):.2f}", 
                size=0.03
            )
            self.gui_elements.append(value_label)
            
            # 减少按钮
            dec_button = gui_manager.createGUIButton(
                pos=(0.83, 0, y_pos), 
                text="-", 
                size=0.03
            )
            self.gui_elements.append(dec_button)
            
            # 增加按钮
            inc_button = gui_manager.createGUIButton(
                pos=(0.93, 0, y_pos), 
                text="+", 
                size=0.03
            )
            self.gui_elements.append(inc_button)
            
            # 注册事件
            self.world.accept(f"dec_{prop}", lambda p=prop, s=step: self._decrease_property(p, s))
            self.world.accept(f"inc_{prop}", lambda p=prop, s=step: self._increase_property(p, s))
            
            # 存储控制信息
            self.property_controls[prop] = {
                'name': name,
                'min': min_val,
                'max': max_val,
                'step': step,
                'value_label': value_label,
                'dec_button': dec_button,
                'inc_button': inc_button
            }
            
    def _cleanup_editor_gui(self):
        """清理编辑器GUI"""
        try:
            if hasattr(self.world, 'gui_manager') and self.world.gui_manager:
                gui_manager = self.world.gui_manager
                
                for element in self.gui_elements:
                    gui_manager.deleteGUIElement(element)
                    
            # 清理事件监听
            tools = ["select", "add", "delete", "paint"]
            for tool in tools:
                self.world.ignore(f"navmesh_tool_{tool}")
                
            functions = ["生成网格", "加载网格", "保存网格", "清除网格", "撤销", "重做"]
            for func in functions:
                self.world.ignore(f"navmesh_func_{func}")
                
            # 清理属性控制事件
            properties = ["cell_size", "cell_height", "agent_height", "agent_radius", 
                         "max_slope", "brush_size"]
            for prop in properties:
                self.world.ignore(f"dec_{prop}")
                self.world.ignore(f"inc_{prop}")
                    
            self.gui_elements.clear()
            self.tool_buttons.clear()
            self.property_controls.clear()
            
        except Exception as e:
            print(f"⚠ 编辑器GUI清理失败: {e}")
            
    def _decrease_property(self, prop_name: str, step: float):
        """减少属性值"""
        if hasattr(self.navmesh_manager, prop_name):
            current_value = getattr(self.navmesh_manager, prop_name)
            control = self.property_controls[prop_name]
            new_value = max(control['min'], current_value - step)
            setattr(self.navmesh_manager, prop_name, new_value)
            
            # 更新显示
            if 'value_label' in control:
                control['value_label'].setText(f"{new_value:.2f}")
                
    def _increase_property(self, prop_name: str, step: float):
        """增加属性值"""
        if hasattr(self.navmesh_manager, prop_name):
            current_value = getattr(self.navmesh_manager, prop_name)
            control = self.property_controls[prop_name]
            new_value = min(control['max'], current_value + step)
            setattr(self.navmesh_manager, prop_name, new_value)
            
            # 更新显示
            if 'value_label' in control:
                control['value_label'].setText(f"{new_value:.2f}")
                
    def set_edit_tool(self, tool: str):
        """设置编辑工具"""
        self.edit_tool = tool
        print(f"✓ 切换到 {tool} 工具")
        
        # 更新按钮状态
        for tool_name, button in self.tool_buttons.items():
            if tool_name == tool:
                # 高亮选中工具
                button.setColor(0.5, 1.0, 0.5, 1.0)  # 绿色
            else:
                # 恢复默认颜色
                button.setColor(1.0, 1.0, 1.0, 1.0)  # 白色
                
    def generate_navmesh(self):
        """生成导航网格"""
        if self.navmesh_manager:
            success = self.navmesh_manager.generate_from_scene()
            if success:
                print("✓ 导航网格生成完成")
            else:
                print("✗ 导航网格生成失败")
                
    def load_navmesh(self):
        """加载导航网格"""
        # 简化实现：加载测试网格
        if self.navmesh_manager:
            self.navmesh_manager._create_test_navmesh()
            print("✓ 导航网格已加载（测试数据）")
            
    def save_navmesh(self):
        """保存导航网格"""
        print("⚠ 保存功能需要实现文件对话框")
        
    def clear_navmesh(self):
        """清除导航网格"""
        if self.navmesh_manager:
            self.navmesh_manager.polygons.clear()
            self.navmesh_manager._update_navmesh_visualization()
            print("✓ 导航网格已清除")
            
    def undo(self):
        """撤销操作"""
        if self.history_index >= 0:
            self.history_index -= 1
            print("✓ 撤销操作")
        else:
            print("⚠ 没有可撤销的操作")
            
    def redo(self):
        """重做操作"""
        if self.history_index < len(self.edit_history) - 1:
            self.history_index += 1
            print("✓ 重做操作")
        else:
            print("⚠ 没有可重做的操作")
            
    def _add_to_history(self, operation: Dict[str, Any]):
        """添加操作到历史记录"""
        # 移除历史记录中超过当前索引的部分
        if self.history_index < len(self.edit_history) - 1:
            self.edit_history = self.edit_history[:self.history_index + 1]
            
        # 添加新操作
        self.edit_history.append(operation)
        
        # 限制历史记录大小
        if len(self.edit_history) > self.max_history_size:
            self.edit_history.pop(0)
        else:
            self.history_index += 1
            
    def select_polygon(self, polygon_id: int):
        """选择多边形"""
        self.selected_polygon = polygon_id
        print(f"✓ 选择多边形: {polygon_id}")
        
    def add_polygon(self, vertices: List[Point3]):
        """添加多边形"""
        if self.navmesh_manager:
            polygon_id = self.navmesh_manager.add_polygon(vertices)
            print(f"✓ 添加多边形: {polygon_id}")
            
            # 添加到历史记录
            operation = {
                'type': 'add_polygon',
                'polygon_id': polygon_id
            }
            self._add_to_history(operation)
            
    def delete_polygon(self, polygon_id: int):
        """删除多边形"""
        if self.navmesh_manager:
            success = self.navmesh_manager.remove_polygon(polygon_id)
            if success:
                print(f"✓ 删除多边形: {polygon_id}")
                
                # 添加到历史记录
                operation = {
                    'type': 'delete_polygon',
                    'polygon_id': polygon_id
                }
                self._add_to_history(operation)
            else:
                print(f"⚠ 无法删除多边形: {polygon_id}")
                
    def paint_walkable_area(self, center: Point3):
        """绘制可行走区域"""
        print(f"✓ 在 {center} 附近绘制可行走区域")
        
    def toggle_edit_mode(self):
        """切换编辑模式"""
        self.edit_mode = not self.edit_mode
        if self.edit_mode:
            print("✓ 进入编辑模式")
        else:
            print("✓ 退出编辑模式")
            
    def set_brush_size(self, size: float):
        """设置笔刷大小"""
        self.brush_size = max(0.1, size)
        print(f"✓ 笔刷大小设置为: {self.brush_size:.2f}")
        
    def get_editor_state(self) -> Dict[str, Any]:
        """获取编辑器状态"""
        return {
            'visible': self.visible,
            'edit_mode': self.edit_mode,
            'selected_tool': self.edit_tool,
            'selected_polygon': self.selected_polygon,
            'brush_size': self.brush_size,
            'polygon_count': len(self.navmesh_manager.polygons) if self.navmesh_manager else 0
        }
        
    def set_editor_state(self, state: Dict[str, Any]):
        """设置编辑器状态"""
        try:
            if 'edit_mode' in state:
                self.edit_mode = state['edit_mode']
                
            if 'selected_tool' in state:
                self.set_edit_tool(state['selected_tool'])
                
            if 'brush_size' in state:
                self.set_brush_size(state['brush_size'])
                
            print("✓ 编辑器状态已恢复")
            
        except Exception as e:
            print(f"⚠ 恢复编辑器状态失败: {e}")
            
    def handle_mouse_click(self, mouse_x: float, mouse_y: float):
        """处理鼠标点击事件"""
        if not self.edit_mode:
            return
            
        # 将屏幕坐标转换为世界坐标（简化实现）
        world_x = mouse_x * 20  # 假设场景大小为20x20
        world_z = mouse_y * 20
        click_point = Point3(world_x, 0, world_z)
        
        if self.edit_tool == "add":
            # 添加多边形（简化为正方形）
            half_size = 0.5
            vertices = [
                Point3(world_x - half_size, 0, world_z - half_size),
                Point3(world_x + half_size, 0, world_z - half_size),
                Point3(world_x + half_size, 0, world_z + half_size),
                Point3(world_x - half_size, 0, world_z + half_size)
            ]
            self.add_polygon(vertices)
            
        elif self.edit_tool == "delete":
            # 删除多边形
            if self.navmesh_manager:
                polygon = self.navmesh_manager.get_polygon_containing_point(click_point)
                if polygon:
                    self.delete_polygon(polygon.polygon_id)
                    
        elif self.edit_tool == "paint":
            # 绘制可行走区域
            self.paint_walkable_area(click_point)
            
        elif self.edit_tool == "select":
            # 选择多边形
            if self.navmesh_manager:
                polygon = self.navmesh_manager.get_polygon_containing_point(click_point)
                if polygon:
                    self.select_polygon(polygon.polygon_id)
                    
    def update(self, dt: float):
        """更新编辑器状态"""
        # 处理键盘输入
        if self.world.mouseWatcherNode.hasMouse():
            mouse_pos = self.world.mouseWatcherNode.getMouse()
            
            # 检查鼠标按键
            if self.world.mouseWatcherNode.isButtonDown(MouseWatcher.getGlobalPointer()):
                if self.last_mouse_pos is None or \
                   (mouse_pos - self.last_mouse_pos).length() > 0.01:
                    self.handle_mouse_click(mouse_pos.x, mouse_pos.y)
                    self.last_mouse_pos = mouse_pos
                    
            # 检查键盘快捷键
            if self.world.mouseWatcherNode.isButtonDown(KeyboardButton.asciiKey('e')):
                self.toggle_edit_mode()
                
    def cleanup(self):
        """清理编辑器资源"""
        self.hide()
        
        # 清理历史记录
        self.edit_history.clear()
        self.history_index = -1
        
        # 清理状态
        self.selected_polygon = None
        self.edit_mode = False