"""Scene manager light operations."""

import os
import shutil
import time
import json
import aiohttp
import asyncio
import inspect
from pathlib import Path

from panda3d.core import (
    ModelPool, ModelRoot, Filename, NodePath, GeomNode, Material, Vec4, Vec3,
    MaterialAttrib, ColorAttrib, Point3, CollisionNode, CollisionSphere, CollisionBox,
    BitMask32, TransparencyAttrib, LColor, TransformState, RenderModeAttrib
)
from panda3d.egg import EggData, EggVertexPool
from direct.actor.Actor import Actor
from RenderPipelineFile.rpplugins.smaa.jitters import halton_seq
from scene import util

class SceneManagerLightMixin:
    def _recreateSpotLight(self, light_node):
        """重新创建聚光灯"""
        try:
            from RenderPipelineFile.rpcore import SpotLight
            from panda3d.core import Vec3
            from core.render_pipeline_utils import get_render_pipeline

            # 创建聚光灯对象
            light = SpotLight()
            light.direction = Vec3(0, 0, -1)
            light.fov = 70
            light.set_color_from_temperature(5 * 1000.0)

            # 恢复保存的属性
            if light_node.hasTag("light_energy"):
                light.energy = float(light_node.getTag("light_energy"))
            else:
                light.energy = 5000

            light.radius = 1000
            light.casts_shadows = True
            light.shadow_map_resolution = 256

            light_pos = light_node.getPos()
            light.setPos(light_pos)

            # 添加到渲染管线
            render_pipeline = get_render_pipeline()
            render_pipeline.add_light(light)

            # 保存光源对象引用
            light_node.setPythonTag("rp_light_object", light)

            # 添加到管理列表（去重）
            if light_node not in self.Spotlight:
                self.Spotlight.append(light_node)

            # 确保灯光节点有正确的标签，以便在场景树更新时被识别
            if not light_node.hasTag("is_scene_element"):
                light_node.setTag("is_scene_element", "1")
            light_node.setTag("is_scene_element", "1")
            light_node.setTag("element_type", "spotlight")
            light_node.setTag("tree_item_type", "LIGHT_NODE")

            if light_node.hasTag("stored_energy"):
                stored_energy = float(light_node.getTag("stored_energy"))
                if stored_energy > 0:
                    light_node.setTag("stored_energy", str(stored_energy))

            user_visible = True
            if light_node.hasTag("user_visible"):
                user_visible = light_node.getTag("user_visible").lower() == "true"

            light_node.setPythonTag("user_visible",user_visible)
            if not user_visible:
                self.toggleLightVisibility(light_node,False)
        except Exception as e:
            print(f"重新创建聚光灯失败: {str(e)}")
            import traceback
            traceback.print_exc()

    def _recreatePointLight(self, light_node):
        """重新创建点光源"""
        try:
            from RenderPipelineFile.rpcore import PointLight
            from core.render_pipeline_utils import get_render_pipeline

            # 创建点光源对象
            light = PointLight()

            # 恢复保存的属性
            if light_node.hasTag("light_energy"):
                light.energy = float(light_node.getTag("light_energy"))
            else:
                light.energy = 5000

            light.radius = 1000
            light.inner_radius = 0.4
            light.set_color_from_temperature(5 * 1000.0)
            light.casts_shadows = True
            light.shadow_map_resolution = 256

            # 设置位置
            light.setPos(light_node.getPos())

            # 添加到渲染管线
            render_pipeline = get_render_pipeline()
            render_pipeline.add_light(light)

            # 保存光源对象引用
            light_node.setPythonTag("rp_light_object", light)

            # 添加到管理列表（去重）
            if light_node not in self.Pointlight:
                self.Pointlight.append(light_node)

            # 确保灯光节点有正确的标签，以便在场景树更新时被识别
            if not light_node.hasTag("is_scene_element"):
                light_node.setTag("is_scene_element", "1")

            light_node.setTag("is_scene_element", "1")
            light_node.setTag("element_type", "pointlight")
            light_node.setTag("tree_item_type", "LIGHT_NODE")

            if light_node.hasTag("stored_energy"):
                stored_energy = float(light_node.getTag("stored_energy"))
                if stored_energy > 0:
                    light_node.setTag("stored_energy", str(stored_energy))

            user_visible = True
            if light_node.hasTag("user_visible"):
                user_visible = light_node.getTag("user_visible").lower()=="true"

            light_node.setPythonTag("user_visible",user_visible)

            if not user_visible:
                self.toggleLightVisibility(light_node,False)
        except Exception as e:
            print(f"重新创建点光源失败: {str(e)}")
            import traceback
            traceback.print_exc()

    def isLightObject(self, nodePath):
        """检查是否为灯光对象"""
        try:
            if not nodePath:
                return False


            # 方法1: 检查PythonTag
            if nodePath.hasPythonTag("rp_light_object"):
                rp_light = nodePath.getPythonTag("rp_light_object")
                if rp_light is not None:
                    return True

            # 方法2: 检查element_type标签
            if nodePath.hasTag("element_type"):
                element_type = nodePath.getTag("element_type")
                if element_type in ["spotlight", "pointlight"]:
                    return True

            # 方法3: 检查tree_item_type标签
            if nodePath.hasTag("tree_item_type"):
                tree_item_type = nodePath.getTag("tree_item_type")
                if tree_item_type == "LIGHT_NODE":
                    return True

            # 方法4: 通过名称模式匹配（作为后备方案）
            node_name = nodePath.getName().lower()
            if "spotlight" in node_name or "pointlight" in node_name:
                return True

            return False
        except Exception as e:
            print(f"检查灯光对象时出错: {e}")
            import traceback
            traceback.print_exc()
            return False

    def toggleLightVisibility(self, light_node, visible):
        """切换灯光可见性"""
        try:
            print(f"切换灯光可见性: {light_node.getName()}, 可见={visible}")

            # 保存用户可见性状态到该特定节点
            light_node.setPythonTag("user_visible", visible)

            # 获取该特定灯光对象
            rp_light_object = light_node.getPythonTag("rp_light_object")
            if not rp_light_object:
                print(f"错误: {light_node.getName()} 未找到RP灯光对象引用")
                return

            # 获取RenderPipeline实例
            from core.render_pipeline_utils import get_render_pipeline
            render_pipeline = get_render_pipeline()

            if not render_pipeline:
                print("错误: 无法获取RenderPipeline实例")
                return

            try:
                if visible:
                    if light_node.hasTag("stored_energy"):
                        stored_energy = float(light_node.getTag("stored_energy"))
                        rp_light_object.energy=stored_energy
                        print(f"已恢复灯光强度: {light_node.getName()}, 能量={stored_energy}")
                    # 启用特定灯光
                    # render_pipeline.add_light(rp_light_object)
                    # print(f"已添加灯光到渲染管线: {light_node.getName()}")
                else:
                    # 禁用特定灯光
                    current_energy = rp_light_object.energy
                    if current_energy != 0.0:
                        light_node.setTag("stored_energy", str(current_energy))
                    elif light_node.hasTag("stored_energy"):
                        stored_energy = float(light_node.getTag("stored_energy"))
                        current_energy = stored_energy
                    else:
                        current_energy = 0.0
                    rp_light_object.energy = 0.0
                    print(f"已禁用灯光: {light_node.getName()}, 保存的能量={current_energy}")
                    # render_pipeline.remove_light(rp_light_object)
                    # print(f"已从渲染管线移除灯光: {light_node.getName()}")
            except Exception as e:
                print(f"操作RenderPipeline灯光时出错: {e}")

            # 控制节点显示状态（可选，主要是视觉上的）
            if visible:
                light_node.show()
            else:
                light_node.hide()

            print(f"灯光可见性设置完成: {visible}")
        except Exception as e:
            print(f"切换灯光可见性失败: {str(e)}")
            import traceback
            traceback.print_exc()

    def _recreateLightFromData(self, node_data, parent_node, name):
        """根据数据重建光源"""
        try:
            light_type = node_data.get('tags', {}).get('light_type', 'spot_light')

            # 创建光源
            if light_type == 'spot_light':
                light_node = self.createSpotLight(pos=node_data.get('pos', (0, 0, 0)))
            else:  # point_light
                light_node = self.createPointLight(pos=node_data.get('pos', (0, 0, 0)))

            if light_node:
                # 设置名称
                light_node.setName(name)

                # 恢复其他属性
                light_data = node_data.get('light_data', {})
                rp_light = light_node.getPythonTag("rp_light_object")
                if rp_light and light_data:
                    if 'energy' in light_data:
                        rp_light.energy = light_data['energy']
                    if 'radius' in light_data:
                        rp_light.radius = light_data['radius']
                    if 'fov' in light_data and hasattr(rp_light, 'fov'):
                        rp_light.fov = light_data['fov']
                    if 'inner_radius' in light_data and hasattr(rp_light, 'inner_radius'):
                        rp_light.inner_radius = light_data['inner_radius']
                    if 'casts_shadows' in light_data and hasattr(rp_light, 'casts_shadows'):
                        rp_light.casts_shadows = light_data['casts_shadows']
                    if 'shadow_map_resolution' in light_data and hasattr(rp_light, 'shadow_map_resolution'):
                        rp_light.shadow_map_resolution = light_data['shadow_map_resolution']

                # 恢复其他标签
                for tag_key, tag_value in node_data.get('tags', {}).items():
                    if tag_key not in ['name', 'light_type']:
                        light_node.setTag(tag_key, str(tag_value))

            return light_node

        except Exception as e:
            print(f"重建光源失败: {e}")
            return None

    def createSpotLight(self, pos=(0, 0, 5)):
        """创建聚光灯
        
        Args:
            pos (tuple): 光源位置 (x, y, z)
            
        Returns:
            NodePath: 创建的聚光灯节点
        """
        try:
            # 检查是否使用RenderPipeline
            if hasattr(self.world, 'render_pipeline') and self.world.render_pipeline:
                from RenderPipelineFile.rpcore import SpotLight
                from core.render_pipeline_utils import get_render_pipeline
                
                # 创建RenderPipeline聚光灯
                from panda3d.core import Vec3
                spotlight = SpotLight()
                spotlight.direction = Vec3(0, 0, -1)  # 向下照射
                spotlight.fov = 70  # 聚光角度
                spotlight.set_color_from_temperature(6500)  # 日光色温
                spotlight.energy = 5000  # 光照强度
                spotlight.radius = 1000  # 光照范围
                spotlight.casts_shadows = True  # 启用阴影
                spotlight.shadow_map_resolution = 256  # 阴影分辨率
                spotlight.setPos(pos)
                
                # 添加到RenderPipeline
                render_pipeline = get_render_pipeline()
                if render_pipeline:
                    render_pipeline.add_light(spotlight)
                    print(f"✓ RenderPipeline聚光灯创建成功，位置: {pos}")
                    
                    # 创建包装节点用于场景树显示
                    light_name = f"Spotlight_{len(self.Spotlight)}"
                    spotlight_node = self.world.render.attachNewNode(light_name)
                    spotlight_node.setPos(*pos)
                    spotlight_node.setTag("light_type", "spot_light")
                    spotlight_node.setTag("is_scene_element", "1")
                    spotlight_node.setTag("tree_item_type", "LIGHT_NODE")
                    spotlight_node.setTag("light_energy", str(getattr(spotlight, "energy", 5000)))
                    spotlight_node.setTag("created_by_user", "1")
                    spotlight_node.setTag("element_type", "spotlight")
                    spotlight_node.setPythonTag("rp_light_object", spotlight)
                    self.Spotlight.append(spotlight_node)
                    return spotlight_node
                else:
                    print("✗ 无法获取RenderPipeline实例")
                    return None
            else:
                # 使用标准Panda3D光源
                from panda3d.core import Spotlight, PerspectiveLens
                
                # 创建聚光灯
                spotlight = Spotlight('spotlight')
                spotlight.setColor((1, 1, 1, 1))  # 白色光
                spotlight.setLens(PerspectiveLens())
                
                # 创建光源节点
                spotlight_node = self.world.render.attachNewNode(spotlight)
                spotlight_node.setPos(pos)
                spotlight_node.setTag("light_type", "spot_light")
                spotlight_node.setTag("is_scene_element", "1")
                spotlight_node.setTag("tree_item_type", "LIGHT_NODE")
                spotlight_node.setTag("created_by_user", "1")
                spotlight_node.setTag("element_type", "spotlight")
                
                # 设置聚光灯方向（向下照射）
                spotlight_node.lookAt(pos[0], pos[1], pos[2] - 5)  # 向下看5个单位
                
                # 设置聚光灯范围
                spotlight.setExponent(1.0)  # 聚光指数
                spotlight.setAttenuation((1, 0.1, 0.01))  # 衰减
                
                # 添加到光源列表
                self.Spotlight.append(spotlight_node)
                
                # 启用光源
                self.world.render.setLight(spotlight_node)
                
                # 启用阴影
                if hasattr(spotlight, 'setShadowCaster'):
                    spotlight.setShadowCaster(True)
                
                print(f"✓ 标准聚光灯创建成功，位置: {pos}")
                return spotlight_node
            
        except Exception as e:
            print(f"✗ 创建聚光灯失败: {e}")
            return None

    def createPointLight(self, pos=(0, 0, 5)):
        """创建点光源
        
        Args:
            pos (tuple): 光源位置 (x, y, z)
            
        Returns:
            NodePath: 创建的点光源节点
        """
        try:
            # 检查是否使用RenderPipeline
            if hasattr(self.world, 'render_pipeline') and self.world.render_pipeline:
                from RenderPipelineFile.rpcore import PointLight
                from core.render_pipeline_utils import get_render_pipeline
                
                # 创建RenderPipeline点光源
                pointlight = PointLight()
                pointlight.set_color_from_temperature(6500)  # 日光色温
                pointlight.energy = 3000  # 光照强度
                pointlight.radius = 1000  # 光照范围
                pointlight.casts_shadows = True  # 启用阴影
                pointlight.shadow_map_resolution = 256  # 阴影分辨率
                pointlight.setPos(pos)
                
                # 添加到RenderPipeline
                render_pipeline = get_render_pipeline()
                if render_pipeline:
                    render_pipeline.add_light(pointlight)
                    print(f"✓ RenderPipeline点光源创建成功，位置: {pos}")
                    
                    # 创建包装节点用于场景树显示
                    light_name = f"Pointlight_{len(self.Pointlight)}"
                    pointlight_node = self.world.render.attachNewNode(light_name)
                    pointlight_node.setPos(*pos)
                    pointlight_node.setTag("light_type", "point_light")
                    pointlight_node.setTag("is_scene_element", "1")
                    pointlight_node.setTag("tree_item_type", "LIGHT_NODE")
                    pointlight_node.setTag("light_energy", str(getattr(pointlight, "energy", 3000)))
                    pointlight_node.setTag("created_by_user", "1")
                    pointlight_node.setTag("element_type", "pointlight")
                    pointlight_node.setPythonTag("rp_light_object", pointlight)
                    self.Pointlight.append(pointlight_node)
                    return pointlight_node
                else:
                    print("✗ 无法获取RenderPipeline实例")
                    return None
            else:
                # 使用标准Panda3D光源
                from panda3d.core import PointLight
                
                # 创建点光源
                pointlight = PointLight('pointlight')
                pointlight.setColor((1, 1, 1, 1))  # 白色光
                pointlight.setAttenuation((1, 0.1, 0.01))  # 衰减设置
                
                # 创建光源节点
                pointlight_node = self.world.render.attachNewNode(pointlight)
                pointlight_node.setPos(pos)
                pointlight_node.setTag("light_type", "point_light")
                pointlight_node.setTag("is_scene_element", "1")
                pointlight_node.setTag("tree_item_type", "LIGHT_NODE")
                pointlight_node.setTag("created_by_user", "1")
                pointlight_node.setTag("element_type", "pointlight")
                
                # 添加到光源列表
                self.Pointlight.append(pointlight_node)
                
                # 启用光源
                self.world.render.setLight(pointlight_node)
                
                # 启用阴影
                if hasattr(pointlight, 'setShadowCaster'):
                    pointlight.setShadowCaster(True)
                
                print(f"✓ 标准点光源创建成功，位置: {pos}")
                return pointlight_node
            
        except Exception as e:
            print(f"✗ 创建点光源失败: {e}")
            return None
