import sys
import os

from core.CustomMouseController import CustomMouseController

# 获取 RenderPipelineFile 的路径
render_pipeline_path = './RenderPipelineFile'
# 将该路径添加到 sys.path 中，确保 Python 能够找到它
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)
sys.path.insert(0, render_pipeline_path)

from RenderPipelineFile.rpcore import RenderPipeline
_global_render_pipeline = None

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

from panda3d.core import *
from panda3d.core import GraphicsOutput, Texture, ConfigVariableManager, WindowProperties

from direct.showbase.ShowBase import ShowBase
import platform

from QMeta3D.QMouseWatcherNode import QMouseWatcherNode

from RenderPipelineFile.rpcore.render_target import RenderTarget
__all__ = ["Meta3DWorld"]

_global_world_instance=None
import builtins


class Meta3DWorld(ShowBase):
    def __init__(self, width=1380, height=750, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1),
                 name="qMeta3D"):

        global _global_world_instance
        global _global_render_pipeline

        _global_world_instance = self

        sort = -100
        self.parent = None

        # 设置基本配置
        loadPrcFileData("", "show-frame-rate-meter 0")
        loadPrcFileData("", "window-type onscreen")  # 改为正常窗口渲染
        loadPrcFileData("", f"win-size {width} {height}")
        loadPrcFileData("", "win-fixed-size #f")  # 允许窗口调整大小

        # 🚀 VR性能优化配置
        loadPrcFileData("", "prefer-single-buffer true")  # 减少缓冲区交换开销
        loadPrcFileData("", "gl-force-flush false")      # 避免强制glFlush导致的性能损失
        loadPrcFileData("", "sync-video false")          # 禁用默认VSync，让OpenVR控制
        loadPrcFileData("", "support-stencil false")     # 禁用不必要的模板缓冲区
        loadPrcFileData("", "clock-mode non-real-time")
        # loadPrcFileData("", "gl-debug true")

        if (is_fullscreen):
            loadPrcFileData("", "fullscreen #t")

        self.render_pipeline = RenderPipeline()
        self.render_pipeline.pre_showbase_init()

        ShowBase.__init__(self)

        # 初始化渲染管线并设置可调整大小的标志
        self.render_pipeline.create(self)
        _global_render_pipeline = self.render_pipeline

        # 正常窗口渲染不需要额外的输出纹理
        # 注释掉离屏渲染相关的纹理创建
        # self.qt_output_tex = Texture("qt_output_tex")
        # self.qt_output_tex.set_format(Texture.F_rgba8)
        # self.qt_output_tex.set_component_type(Texture.T_unsigned_byte)
        # self.win.add_render_texture(self.qt_output_tex, GraphicsOutput.RTM_copy_ram)

        #self.screenTexture = Texture()
        #self.screenTexture.setMinfilter(Texture.FTLinear)
        #self.screenTexture.setFormat(Texture.FRgba32)
        #self.screenTexture.set_wrap_u(Texture.WM_clamp)
        #self.screenTexture.set_wrap_v(Texture.WM_clamp)

        # buff_size_x = int(self.win.get_x_size() * size)
        # buff_size_y = int(self.win.get_y_size() * size)
        # winprops = WindowProperties()
        # winprops.set_size(buff_size_x, buff_size_y)
        #
        #
        # props = FrameBufferProperties()
        # props.set_rgb_color(True)
        # props.set_rgba_bits(8, 8, 8, 8)
        # props.set_depth_bits(8)

        # self.buff = self.graphicsEngine.make_output(
        #     self.pipe, name, sort,
        #     props, winprops,
        #     GraphicsPipe.BF_resizeable,
        #     self.win.get_gsg(), self.win)

        #self.screenTexture = render_pipeline._final_stage.target.color_tex

        #self.buff.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
        # self.buff.set_sort(sort)



        #self.cam = self.makeCamera(self.buff)
        #self.render_pipeline._showbase.cam=self.makeCamera(self.buff)

        #self.render_pipeline._showbase.cam=self.makeCamera(self.buff)

        #self.render_pipeline._showbase.camera.reparentTo(self.render)
        #base.camera.reparentTo(self.render)
        #self.cam.reparentTo(self.render)  # 可选同步

        #render_pipeline.set_camera(self.cam)

        #添加渲染效果
        #self.cam = self.render_pipeline._showbase.cam
        #self.camNode = self.cam.node()
        #self.camLens = self.camNode.get_lens()
        self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
        #self.render_pipeline.daytime_mgr.update()


        # if clear_color is None:
        #     self.buff.set_clear_active(GraphicsOutput.RTPColor, False)
        # else:
        #     self.buff.set_clear_color(clear_color)
        #     self.buff.set_clear_active(GraphicsOutput.RTPColor, True)

        # self.disableMouse()
        self.mouse_controller = CustomMouseController(self)
        self.mouse_controller.setUp()

        # 添加错误处理钩子
        self.accept("transform_state_error", self._handle_transform_error)

    def _handle_transform_error(self):
        """处理TransformState相关的错误"""
        try:
            from panda3d.core import TransformState, RenderState
            TransformState.clear_cache()
            RenderState.clear_cache()
            print("已清理TransformState和RenderState缓存")
        except Exception as e:
            print(f"清理缓存时出错: {e}")

    def render_pipeline(self):
        """获取 RenderPipeline 实例"""
        return self._render_pipeline


    def set_parent(self, parent: QWidget):
        self.parent = parent
        self.mouseWatcherNode = QMouseWatcherNode(parent)

    def getAspectRatio(self, win = None):
        if win is None and self.parent is not None:
            return float(self.parent.width()) / float(self.parent.height())
        else:
            return super().getAspectRatio(win)

def get_render_pipeline():
    """获取全局 RenderPipeline 单例"""
    if _global_render_pipeline is None:
        raise RuntimeError(
            "RenderPipeline has not been initialized yet. Please create a 3DWorld instance first.")
    return _global_render_pipeline

def resize_buffer(self, width: int, height: int):
    props = WindowProperties()
    props.set_size(width, height)
    self.win.request_properties(props)

    # 重新分配输出贴图的大小
    self.qt_output_tex.set_x_size(width)
    self.qt_output_tex.set_y_size(height)

    # 更新 lens 的 aspect ratio
    if self.camLens:
        self.camLens.set_film_size(width, height)  # 或 set_aspect_ratio(width / height)

    # 强制更新窗口（有时在 Qt 内嵌时需要）
    self.graphicsEngine.open_windows()