#include "pch.h"
#include "ModelRender.h"


ModelRender* ModelRender::s_instance = nullptr;

ModelRender::Matrix3f ModelRender::buildCameraProjection(int width, int height)
{
    Matrix3f m;

    if (m_camera.isEnabled()) {
        // 考虑摄像机缩放和平移
        GLfloat zoom = m_camera.getZoom();
        Vector2f pos = m_camera.getPosition();
        m = Matrix3f(
            2.0f * zoom / width, 0.0f, -1.0f - (2.0f * zoom * pos.x / width),
            0.0f, -2.0f * zoom / height, 1.0f + (2.0f * zoom * pos.y / height),
            0.0f, 0.0f, 1.0f
        );
    }
    else {
        // 原始投影矩阵
        m = Matrix3f(
            2.0f / width, 0.0f, -1.0f,
            0.0f, -2.0f / height, 1.0f,
            0.0f, 0.0f, 1.0f
        );
    }

    return m;
}

void ModelRender::initialize() noexcept(false)
{
    if (m_isInitialized) return;

    logger.info("Initializing ModelRender...");

    // 初始化渲染系统
    RenderSystem::beginInitialization();
    RenderSystem::initRenderThread();

    logGLInfo();
    setupGLState();

    try {
        compileDefaultShader();

        // 初始化所有非默认着色器的基础信息
        initNonDefaultShaders();

    }
    catch (std::runtime_error ex) {
        logger.error("Failed to compile default shader: {}", ex.what());
        throw ex;
    }


    createDefaultTexture();
    RenderSystem::viewport(0, 0, m_viewportSize.width, m_viewportSize.height);
    RenderSystem::finishInitialization();

    try {
        // TODO: 替换为字体

        // 初始化默认字体（可替换为你自己的 TTF 数据）
        ByteBuffer fontData;
        try {
            fontData = RenderSystem::loadFont("FZYTK.TTF");
        }
        catch (std::exception e) {
            logger.warning("Failed to load Arial.ttf, trying fallback fonts", e);
            // 尝试其他字体
            try {
                fontData = RenderSystem::loadFont("arial.ttf");
            }
            catch (std::exception e2) {
                try {
                    fontData = RenderSystem::loadFont("times.ttf");
                }
                catch (std::exception e3) {
                    logger.error("All font loading attempts failed");
                }
            }
        }

        if (!fontData.empty()) {
            m_defaultTextRenderer = std::make_unique<TextRenderer>(m_fontBitmapSize.width, m_fontBitmapSize.height, m_fontFirstChar, m_fontCharCount);
            RenderSystem::checkGLError("TextRenderer constructor");

            m_defaultTextRenderer->initialize(fontData, 20.0f);
            RenderSystem::checkGLError("m_defaultTextRenderer initialization");

            if (!m_defaultTextRenderer->isInitialized()) {
                logger.error("TextRenderer failed to initialize properly");
            }
        }
        else {
            logger.error("No valid font data available for text rendering");
        }
    }
    catch (std::exception e) {
        logger.warning("Failed to initialize default text renderer", e);
    }

    m_isInitialized = true;
    logger.info("ModelRender m_isInitialized successfully");
}

void ModelRender::initNonDefaultShaders()
{
    std::vector<std::unique_ptr<CompleteShader>> shaderList = ShaderManagement::s_shaderList;
    if (shaderList.empty()) {
        logger.info("No shaders found to initialize");
        return;
    }

    int nonDefaultCount = 0;
    for (auto& shader : shaderList) {
        // 跳过默认着色器，只初始化非默认的
        if (shader->isDefaultShader()) {
            continue;
        }

        try {
            // 获取着色器程序
            ShaderProgram* program = ShaderManagement::getShaderProgram(shader->getShaderName());
            if (program == nullptr) {
                logger.warning("Shader program not found for: {}", shader->getShaderName());
                continue;
            }

            // 设置着色器的基础uniforms（主要是顶点坐标相关的）
            initShaderBasicUniforms(program, shader.get());
            nonDefaultCount++;

            logger.debug("Initialized non-default shader: {}", shader->getShaderName());

        }
        catch (std::exception e) {
            logger.error("Failed to initialize non-default shader: {}", shader->getShaderName(), e);
        }
    }

    logger.info("Initialized {} non-default shaders", nonDefaultCount);
}

void ModelRender::initShaderBasicUniforms(ShaderProgram* program, CompleteShader* shader)
{
    program->use();

    try {
        // 设置基础的变换矩阵为单位矩阵
        setUniformMatrix3(program, "uModelMatrix", Matrix3f(1.0f));
        setUniformMatrix3(program, "uViewMatrix", Matrix3f(1.0f));

        // 设置投影矩阵（使用当前视口尺寸）
        Matrix3f projection = buildOrthoProjection(m_viewportSize.width, m_viewportSize.height);
        setUniformMatrix3(program, "uProjectionMatrix", projection);

        // 设置基础颜色为白色
        setUniformVec4Internal(program, "uColor", Vector4f(1.0f, 1.0f, 1.0f, 1.0f));

        // 设置基础不透明度
        setUniformFloatInternal(program, "uOpacity", 1.0f);

        // 设置纹理单元（如果有纹理的话）
        setUniformIntInternal(program, "uTexture", 0);

        RenderSystem::checkGLError("initShaderBasicUniforms_" + shader->getShaderName());

    }
    catch (...) {
        program->stop();
        throw;
    }
}

void ModelRender::logGLInfo()
{
    RenderSystem::logDetailedGLInfo();
}

void ModelRender::uploadLightsToShader(ShaderProgram* sp, Model2D& model)
{
    std::vector<LightSource> lights = model.getLights();
    int idx = 0;

    for (int i = 0; i < lights.size() && idx < m_maxLightCount; i++) {
        LightSource l = lights[i];
        if (!l.isEnabled()) continue;
        std::string idxStr = std::to_string(idx);

        // 基础属性
        setUniformVec2Internal(sp, "uLightsPos[" + idxStr + "]", l.isAmbient() ? Vector2f(0.0f, 0.0f) : l.getPosition());
        setUniformVec3Internal(sp, "uLightsColor[" + idxStr + "]", l.getColor());
        setUniformFloatInternal(sp, "uLightsIntensity[" + idxStr + "]", l.getIntensity());
        setUniformIntInternal(sp, "uLightsIsAmbient[" + idxStr + "]", l.isAmbient() ? 1 : 0);

        // 辉光相关（如果没有被设置也安全地上传默认值）
        //setUniformIntInternal(sp, "uLightsIsGlow[" + idxStr + "]", l.isGlow() ? 1 : 0);
        //setUniformVec2Internal(sp, "uLightsGlowDir[" + idxStr + "]", l.getGlowDirection() ? l.getGlowDirection() : Vector2f(0.0f, 0.0f));
        //setUniformFloatInternal(sp, "uLightsGlowIntensity[" + idxStr + "]", l.getGlowIntensity());
        //setUniformFloatInternal(sp, "uLightsGlowRadius[" + idxStr + "]", l.getGlowRadius());
        //setUniformFloatInternal(sp, "uLightsGlowAmount[" + idxStr + "]", l.getGlowAmount());

        idx++;
    }

    // 上传实际有效光源数量
    setUniformIntInternal(sp, "uLightCount", idx);

    // 禁用剩余槽位（确保 shader 中不会读取到垃圾值）
    for (int i = idx; i < m_maxLightCount; i++) {
        std::string idxStr = std::to_string(i);
        setUniformFloatInternal(sp, "uLightsIntensity[" + idxStr + "]", 0.0f);
        setUniformIntInternal(sp, "uLightsIsAmbient[" + idxStr + "]", 0);
        setUniformVec3Internal(sp, "uLightsColor[" + idxStr + "]", Vector3f(0.0f, 0.0f, 0.0f));
        setUniformVec2Internal(sp, "uLightsPos[" + idxStr + "]", Vector2f(0.0f, 0.0f));

        // 关闭辉光槽
        setUniformIntInternal(sp, "uLightsIsGlow[" + idxStr + "]", 0);
        setUniformVec2Internal(sp, "uLightsGlowDir[" + idxStr + "]", Vector2f(0.0f, 0.0f));
        setUniformFloatInternal(sp, "uLightsGlowIntensity[" + idxStr + "]", 0.0f);
        setUniformFloatInternal(sp, "uLightsGlowRadius[" + idxStr + "]", 0.0f);
        setUniformFloatInternal(sp, "uLightsGlowAmount[" + idxStr + "]", 0.0f);
    }
}

void ModelRender::setupGLState()
{
    RenderSystem::checkGLError("setupGLState_start");

    RenderSystem::clearColor(m_clearColor.x, m_clearColor.y, m_clearColor.z, m_clearColor.w);
    RenderSystem::checkGLError("after_clearColor");

    if (m_enableBlending) {
        RenderSystem::enableBlend();
        RenderSystem::checkGLError("after_enableBlend");

        RenderSystem::blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        RenderSystem::checkGLError("after_blendFunc");
    }
    else {
        RenderSystem::disableBlend();
        RenderSystem::checkGLError("after_disableBlend");
    }

    if (m_enableDepthTest) {
        RenderSystem::enableDepthTest();
        RenderSystem::checkGLError("after_enableDepthTest");

        RenderSystem::depthFunc(GL_LEQUAL);
        RenderSystem::checkGLError("after_depthFunc");

        RenderSystem::depthMask(true);
        RenderSystem::checkGLError("after_depthMask");

        RenderSystem::clearDepth(1.0);
        RenderSystem::checkGLError("after_clearDepth");
    }
    else {
        RenderSystem::disableDepthTest();
        RenderSystem::checkGLError("after_disableDepthTest");
    }

    RenderSystem::checkGLError("after_disableCullFace");
}

void ModelRender::compileDefaultShader()
{
    ShaderManagement::compileAllShaders();
    m_defaultProgram = ShaderManagement::getDefaultProgram();
    if (m_defaultProgram == nullptr) {
        throw std::runtime_error("Failed to compile default shader: no default shader found");
    }
}

void ModelRender::createDefaultTexture()
{
    RenderSystem::assertOnRenderThread();
    m_defaultTextureId = RenderSystem::createDefaultTexture();
    RenderSystem::checkGLError("createDefaultTexture");
}

void ModelRender::cleanup()
{
    if (!m_isInitialized) return;

    logger.info("Cleaning up ModelRender...");

    // mesh resources
    for (auto& [k, r] : m_meshResources) r.dispose();
    m_meshResources.clear();

    // 使用新的着色器管理系统清理着色器
    ShaderManagement::cleanup();
    m_defaultProgram = nullptr;

    // textures
    if (m_defaultTextureId != 0) {
        RenderSystem::deleteTextures(m_defaultTextureId);
        m_defaultTextureId = 0;
    }

    m_isInitialized = false;
    logger.info("ModelRender cleaned up");
}

void ModelRender::render(GLfloat deltaTime, Model2D& model)
{
    if (!m_isInitialized) throw IllegalStateException("ModelRender not m_isInitialized");

    // 确保在渲染线程
    RenderSystem::assertOnRenderThread();

    // 添加前置错误检查
    RenderSystem::checkGLError("render_start");

    // 物理系统更新
    PhysicsSystem* physics = model.getPhysics();
    if (physics && physics->isEnabled()) {
        physics->update(deltaTime, model);
    }

    model.update(deltaTime);

    // 检查清除操作前的状态
    RenderSystem::checkGLError("before_clear");
    RenderSystem::clear(GL_COLOR_BUFFER_BIT | (m_enableDepthTest ? GL_DEPTH_BUFFER_BIT : 0));
    RenderSystem::checkGLError("after_clear");

    // 检查着色器程序
    if (!m_defaultProgram || m_defaultProgram->getProgramId() == 0) {
        logger.error("Default shader program is not m_isInitialized");
        return;
    }

    // 设置投影与视图矩阵（使用摄像机变换）
    Matrix3f proj = buildCameraProjection(m_viewportSize.width, m_viewportSize.height);
    Matrix3f view(1.0f);

    // 1. 首先设置默认着色器
    m_defaultProgram->use();
    RenderSystem::checkGLError("after_use_default_program");

    // 设置默认着色器的投影与视图
    setUniformMatrix3(m_defaultProgram, "uProjectionMatrix", proj);
    setUniformMatrix3(m_defaultProgram, "uViewMatrix", view);
    RenderSystem::checkGLError("after_set_default_matrices");

    // 设置摄像机Z轴位置（如果着色器支持）
    setUniformFloatInternal(m_defaultProgram, "uCameraZ", m_camera.getZPosition());
    RenderSystem::checkGLError("after_set_camera_z");

    // 添加光源数据上传到默认着色器
    uploadLightsToShader(m_defaultProgram, model);
    RenderSystem::checkGLError("after_upload_lights");

    // 2. 设置非默认着色器的顶点坐标相关uniform
    setupNonDefaultShaders(proj, view);
    RenderSystem::checkGLError("after_setup_non_default_shaders");

    // 在渲染光源位置前检查
    RenderSystem::checkGLError("before_render_light_positions");
    renderLightPositions(model);
    RenderSystem::checkGLError("after_render_light_positions");

    // 递归渲染所有根部件（使用默认着色器）
    Matrix3f identity = Matrix3f(1.0f);
    for (auto& p : model.getParts()) {
        if (p->getParent()) continue;
        renderPartRecursive(p, identity);
    }
    RenderSystem::checkGLError("after_render_parts");

    if (m_renderColliders && physics) {
        renderPhysicsColliders(physics);
        RenderSystem::checkGLError("after_render_colliders");
    }

    //if (m_defaultTextRenderer) {
    //    std::string camInfo = std::string.format("Camera X: %.2f Y: %.2f Zoom: %.2f",
    //            m_camera.getPosition().x,
    //            m_camera.getPosition().y,
    //            m_camera.getZoom());
    //    GLfloat x = 10.0f;
    //    GLfloat y = m_viewportSize.height - 30.0f;
    //    Vector4f color = new Vector4f(1.0f, 1.0f, 1.0f, 1.0f);
    //    renderText(camInfo, x, y, color);
    //    RenderSystem::checkGLError("renderText");
    //}

    RenderSystem::checkGLError("render_end");
}


void ModelRender::renderThumbnail(Model2D& model, GLfloat x, GLfloat y, GLfloat width, GLfloat height)
{
    if (!m_isInitialized) throw IllegalStateException("ModelRender not m_isInitialized");

    RenderSystem::assertOnRenderThread();
    RenderSystem::checkGLError("renderThumbnail_start");

    // 保存原始状态以便恢复
    bool originalRenderColliders = m_renderColliders;
    bool originalRenderLightPositions = m_renderLightPositions;
    int originalViewportWidth = m_viewportSize.width;
    int originalViewportHeight = m_viewportSize.height;

    try {
        // 设置缩略图专用状态
        m_renderColliders = false;
        m_renderLightPositions = false;

        // 设置缩略图视口（屏幕坐标）
        RenderSystem::viewport((int)x, (int)y, (int)width, (int)height);

        // 清除缩略图区域
        RenderSystem::clear(GL_COLOR_BUFFER_BIT | (m_enableDepthTest ? GL_DEPTH_BUFFER_BIT : 0));
        RenderSystem::checkGLError("thumbnail_after_clear");

        // 简化版的模型更新（跳过物理系统）
        model.update(0.016f); // 使用固定时间步长

        // 计算模型边界和缩放比例
        ThumbnailBounds bounds = calculateThumbnailBounds(model, width, height);

        // 设置缩略图专用的正交投影（固定位置，不受摄像机影响）
        Matrix3f proj = buildThumbnailProjection(width, height);
        Matrix3f view = Matrix3f(1.0f);

        // 使用默认着色器
        m_defaultProgram->use();
        RenderSystem::checkGLError("thumbnail_after_use_program");

        // 设置基础变换矩阵
        setUniformMatrix3(m_defaultProgram, "uProjectionMatrix", proj);
        setUniformMatrix3(m_defaultProgram, "uViewMatrix", view);
        setUniformFloatInternal(m_defaultProgram, "uCameraZ", 0.0f); // 固定Z位置
        RenderSystem::checkGLError("thumbnail_after_set_matrices");

        // 简化光源：只使用环境光
        setupThumbnailLighting(m_defaultProgram, model);
        RenderSystem::checkGLError("thumbnail_after_setup_lighting");

        // 应用缩放和平移确保模型完全可见
        Matrix3f thumbnailTransform(
            bounds.scale, 0, bounds.offsetX,
            0, bounds.scale, bounds.offsetY,
            0, 0, 1
        );

        // 递归渲染所有根部件（应用缩略图专用变换）
        for (auto& p : model.getParts()) {
            if (p->getParent()) continue;
            renderPartForThumbnail(p.get(), thumbnailTransform);
        }
        RenderSystem::checkGLError("thumbnail_after_render_parts");

    }
    catch (...) {
        // 恢复原始状态
        m_renderColliders = originalRenderColliders;
        m_renderLightPositions = originalRenderLightPositions;
        RenderSystem::viewport(0, 0, originalViewportWidth, originalViewportHeight);
        throw;
    }

    RenderSystem::checkGLError("renderThumbnail_end");
}


ModelRender::ThumbnailBounds ModelRender::calculateThumbnailBounds(Model2D& model, GLfloat thumbWidth, GLfloat thumbHeight)
{
    ThumbnailBounds bounds;

    // 初始化为极值
    bounds.minX = std::numeric_limits<GLfloat>::max();
    bounds.maxX = std::numeric_limits<GLfloat>::min();
    bounds.minY = std::numeric_limits<GLfloat>::max();
    bounds.maxY = std::numeric_limits<GLfloat>::min();

    // 计算模型的世界坐标边界（递归遍历所有部件）
    calculateModelBounds(model, bounds, Matrix3f(1.0f));

    // 如果模型没有有效边界，使用默认值
    if (bounds.minX > bounds.maxX) {
        bounds.minX = -50.0f;
        bounds.maxX = 50.0f;
        bounds.minY = -50.0f;
        bounds.maxY = 50.0f;
    }

    // 计算模型宽度和高度
    GLfloat modelWidth = bounds.maxX - bounds.minX;
    GLfloat modelHeight = bounds.maxY - bounds.minY;

    // 计算中心点
    GLfloat centerX = (bounds.minX + bounds.maxX) * 0.5f;
    GLfloat centerY = (bounds.minY + bounds.maxY) * 0.5f;

    // 计算缩放比例（考虑边距）
    GLfloat margin = 0.1f; // 10%边距
    GLfloat scaleX = (thumbWidth * (1 - margin)) / modelWidth;
    GLfloat scaleY = (thumbHeight * (1 - margin)) / modelHeight;
    bounds.scale = std::min(scaleX, scaleY);

    // 计算偏移量（将模型中心对齐到缩略图中心）
    bounds.offsetX = -centerX;
    bounds.offsetY = -centerY;

    return bounds;
}

void ModelRender::calculateModelBounds(Model2D& model, ThumbnailBounds bounds, Matrix3f parentTransform)
{
    for (auto& part : model.getParts()) {
        if (part->getParent()) continue; // 只处理根部件

        // 计算部件的世界变换
        part->updateWorldTransform(parentTransform, false);
        Matrix3f worldTransform = part->getWorldTransform();

        // 计算部件的边界
        calculatePartBounds(part.get(), bounds, worldTransform);

        // 递归处理子部件
        for (auto& child : part->getChildren()) {
            calculateModelBoundsForPart(child.get(), bounds, worldTransform);
        }
    }
}


void ModelRender::calculateModelBoundsForPart(ModelPart* part, ThumbnailBounds bounds, Matrix3f parentTransform)
{
    part->updateWorldTransform(parentTransform, false);
    Matrix3f worldTransform = part->getWorldTransform();

    calculatePartBounds(part, bounds, worldTransform);

    for (auto& child : part->getChildren()) {
        calculateModelBoundsForPart(child.get(), bounds, worldTransform);
    }
}


void ModelRender::calculatePartBounds(ModelPart* part, ThumbnailBounds bounds, Matrix3f worldTransform)
{
    for (auto& mesh : part->getMeshes()) {
        if (!mesh->isVisible()) continue;

        // 获取网格的顶点数据
        std::vector<GLfloat>&& vertices = mesh->getVertices(); // 假设有这个方法获取原始顶点
        if (vertices.empty()) continue;

        // 变换顶点并更新边界
        for (int i = 0; i < vertices.size(); i += 3) { // 假设顶点格式：x, y, z
            GLfloat x = vertices[i];
            GLfloat y = vertices[i + 1];

            // 应用世界变换
            Vector3f transformed(x, y, 1.0f);
            // transformed = transformed * worldTransform;
            transformed = worldTransform * transformed;

            // 更新边界
            bounds.minX = std::min(bounds.minX, transformed.x);
            bounds.maxX = std::max(bounds.maxX, transformed.x);
            bounds.minY = std::min(bounds.minY, transformed.y);
            bounds.maxY = std::max(bounds.maxY, transformed.y);
        }
    }
}

ModelRender::Matrix3f ModelRender::buildThumbnailProjection(GLfloat width, GLfloat height)
{
    // 标准正交投影，不受摄像机影响
    Matrix3f m(
        2.0f / width, 0.0f, -1.0f,
        0.0f, -2.0f / height, 1.0f,
        0.0f, 0.0f, 1.0f
    );
    return m;
}

void ModelRender::renderPartForThumbnail(ModelPart* part, Matrix3f parentTransform)
{
    part->updateWorldTransform(parentTransform, false);
    Matrix3f world = part->getWorldTransform();

    setPartUniforms(m_defaultProgram, part);
    setUniformMatrix3(m_defaultProgram, "uModelMatrix", world);

    for (auto& mesh : part->getMeshes()) {
        renderMeshForThumbnail(mesh.get(), world);
    }

    for (auto& child : part->getChildren()) {
        renderPartForThumbnail(child.get(), world);
    }
}

void ModelRender::renderMeshForThumbnail(Mesh2D* mesh, Matrix3f modelMatrix)
{
    if (!mesh->isVisible()) return;

    Matrix3f matToUse = mesh->isBakedToWorld() ? Matrix3f(1.0f) : Matrix3f(modelMatrix);

    if (mesh->getTexture()) {
        mesh->getTexture().bind(0);
        setUniformIntInternal(m_defaultProgram, "uTexture", 0);
    }
    else {
        RenderSystem::bindTexture(m_defaultTextureId);
        setUniformIntInternal(m_defaultProgram, "uTexture", 0);
    }

    setUniformMatrix3(m_defaultProgram, "uModelMatrix", matToUse);
    mesh->draw(m_defaultProgram->getProgramId(), matToUse);

    RenderSystem::checkGLError("renderMeshForThumbnail");
}

void ModelRender::setupThumbnailLighting(ShaderProgram* sp, Model2D& model)
{
    auto& lights = model.getLights();
    int ambientLightCount = 0;

    // 查找环境光
    for (int i = 0; i < lights.size() && ambientLightCount < 1; i++) {
        LightSource light = lights[i];
        if (light.isEnabled() && light.isAmbient()) {
            setUniformVec2Internal(sp, "uLightsPos[0]", Vector2f(0.0f, 0.0f));
            setUniformVec3Internal(sp, "uLightsColor[0]", light.getColor());
            setUniformFloatInternal(sp, "uLightsIntensity[0]", light.getIntensity());
            setUniformIntInternal(sp, "uLightsIsAmbient[0]", 1);
            setUniformIntInternal(sp, "uLightsIsGlow[0]", 0);
            ambientLightCount++;
        }
    }

    // 如果没有环境光，创建一个默认的环境光
    if (ambientLightCount == 0) {
        setUniformVec2Internal(sp, "uLightsPos[0]", Vector2f(0.0f, 0.0f));
        setUniformVec3Internal(sp, "uLightsColor[0]", Vector3f(0.8f, 0.8f, 0.8f));
        setUniformFloatInternal(sp, "uLightsIntensity[0]", 1.0f);
        setUniformIntInternal(sp, "uLightsIsAmbient[0]", 1);
        setUniformIntInternal(sp, "uLightsIsGlow[0]", 0);
        ambientLightCount = 1;
    }

    setUniformIntInternal(sp, "uLightCount", ambientLightCount);

    // 禁用所有其他光源槽位
    for (int i = ambientLightCount; i < m_maxLightCount; i++) {
        std::string idxStr = std::to_string(i);
        setUniformFloatInternal(sp, "uLightsIntensity[" + idxStr + "]", 0.0f);
        setUniformIntInternal(sp, "uLightsIsAmbient[" + idxStr + "]", 0);
    }
}

void ModelRender::setupNonDefaultShaders(Matrix3f projection, Matrix3f view)
{
    auto& shaderList = ShaderManagement::s_shaderList;
    if (shaderList.empty()) {
        return;
    }

    // 保存当前绑定的着色器程序
    int currentProgram = 0;
    // Java: int curProgram = GL11.glGetIntegerv(GL20.GL_CURRENT_PROGRAM);
    glGetIntegerv(GL_CURRENT_PROGRAM, &currentProgram);

    try {
        for (auto& shader : shaderList) {
            // 跳过默认着色器
            if (shader->isDefaultShader()) {
                continue;
            }

            try {
                // 获取着色器程序
                ShaderProgram* program = ShaderManagement::getShaderProgram(shader->getShaderName());
                if (!program || program->getProgramId() == 0) {
                    continue;
                }

                program->use();

                // 只设置顶点坐标相关的uniform
                setUniformMatrix3(program, "uProjectionMatrix", projection);
                setUniformMatrix3(program, "uViewMatrix", view);

                // 设置基础模型矩阵为单位矩阵
                setUniformMatrix3(program, "uModelMatrix", Matrix3f(1.0f));

                // 设置摄像机Z轴位置
                setUniformFloatInternal(program, "uCameraZ", m_camera.getZPosition());

                RenderSystem::checkGLError("setupNonDefaultShaders_" + shader->getShaderName());

            }
            catch (std::exception e) {
                logger.warning("Failed to setup non-default shader: {}", shader->getShaderName(), e);
            }
        }
    }
    catch (...) {
        // 恢复之前绑定的着色器程序
        if (currentProgram != 0) {
            glUseProgram(currentProgram);
        }
        throw;
    }
}

void ModelRender::renderLightPositions(Model2D& model)
{
    if (!renderLightPositions) return;
    // 设置灯泡颜色为光源的颜色
    for (LightSource light : model.getLights()) {
        if (!light.isEnabled()) continue;

        // 使用光源的颜色来绘制灯泡
        Vector4f lightColor(light.getColor().x, light.getColor().y, light.getColor().z, 1.0f);
        setUniformVec4Internal(m_defaultProgram, "uColor", lightColor);

        // 绘制灯泡形状
        drawLightBulb(light.getPosition(), light.getIntensity());

        if (light.isAmbient()) {
            drawCrossMark(light.getPosition(), light.getIntensity());
        }
    }
    // 恢复原始颜色
    setUniformVec4Internal(m_defaultProgram, "uColor", Vector4f(1, 1, 1, 1));
}

void ModelRender::drawLightBulb(Vector2f position, GLfloat intensity)
{
    Tesselator& tesselator = Tesselator::getInstance();
    BufferBuilder& builder = tesselator.getBuilder();
    GLfloat bulbSize = 3.0f + (intensity / 10.0f);
    int segments = 16;
    builder.begin(GL_TRIANGLE_FAN, segments + 2);

    builder.vertex(position.x, position.y, 0.5f, 0.5f);

    for (int i = 0; i <= segments; i++) {
        double angle = 2.0 * c_pi * i / segments;
        GLfloat x = position.x + bulbSize * std::cosf(angle);
        GLfloat y = position.y + bulbSize * std::sinf(angle);
        builder.vertex(x, y, 0.5f, 0.5f);
    }
    tesselator.end();
}

void ModelRender::drawCrossMark(Vector2f position, GLfloat size)
{
    Tesselator& tesselator = Tesselator::getInstance();
    BufferBuilder& builder = tesselator.getBuilder();

    GLfloat crossSize = size * 0.8f;

    // 绘制水平线
    builder.begin(GL_LINES, 2);
    builder.vertex(position.x - crossSize, position.y, 0.5f, 0.5f);
    builder.vertex(position.x + crossSize, position.y, 0.5f, 0.5f);
    tesselator.end();

    // 绘制垂直线
    builder.begin(GL_LINES, 2);
    builder.vertex(position.x, position.y - crossSize, 0.5f, 0.5f);
    builder.vertex(position.x, position.y + crossSize, 0.5f, 0.5f);
    tesselator.end();
}

void ModelRender::renderPartRecursive(ModelPart* part, Matrix3f parentMat)
{
    // 确保 part 的 local/world 矩阵被计算（会更新 transformDirty）
    part->updateWorldTransform(parentMat, false);

    // 直接使用已经计算好的 worldTransform
    Matrix3f world = part->getWorldTransform();

    // 先设置部件相关的 uniform（opacity / blendMode / color 等）
    setPartUniforms(m_defaultProgram, part);

    // 把 world 矩阵传给 shader（uModelMatrix）
    setUniformMatrix3(m_defaultProgram, "uModelMatrix", world);

    // 绘制本节点的所有 mesh（将 world 传入 renderMesh）
    for (auto& mesh : part->getMeshes()) {
        renderMesh(mesh.get(), world);
    }

    // 递归渲染子节点，继续传入当前 world 作为子节点的 parent
    for (auto& child : part->getChildren()) {
        renderPartRecursive(child.get(), world);
    }
}

void ModelRender::renderMesh(Mesh2D* mesh, Matrix3f modelMatrix)
{
    if (!mesh->isVisible()) return;

    // 如果 mesh 已经被烘焙到世界坐标，则传 identity 矩阵给 shader（防止重复变换）
    Matrix3f matToUse = mesh->isBakedToWorld() ? Matrix3f(1.0f) : Matrix3f(modelMatrix);

    // 手动应用摄像机偏移
    Vector2f offset = getCameraOffset();
    matToUse[2][0] -= offset.x;  // 第3列第1行（平移X）
    matToUse[2][1] -= offset.y;  // 第3列第2行（平移Y）

    // 设置纹理相关的uniform
    if (mesh->getTexture()) {
        mesh->getTexture().bind(0); // 绑定到纹理单元0
        setUniformIntInternal(m_defaultProgram, "uTexture", 0);
    }
    else {
        // 使用默认白色纹理
        RenderSystem::bindTexture(m_defaultTextureId);
        setUniformIntInternal(m_defaultProgram, "uTexture", 0);
    }

    // 将模型矩阵设置为当前 mesh 使用的矩阵（shader 内名为 uModelMatrix）
    setUniformMatrix3(m_defaultProgram, "uModelMatrix", matToUse);

    // 调用 Mesh2D 的 draw 方法，传入当前使用的着色器程序和变换矩阵
    mesh->draw(m_defaultProgram->getProgramId(), matToUse);

    RenderSystem::checkGLError("renderMesh");
}

void ModelRender::renderPhysicsColliders(PhysicsSystem* physics)
{
    if (!physics) {
        logger.warning("renderPhysicsColliders: physics system is nullptr");
        return;
    }

    // 设置渲染状态
    RenderSystem::checkGLError("before_set_line_width");
    RenderSystem::lineWidth(m_colliderLineWidth);
    RenderSystem::checkGLError("after_set_line_width");

    RenderSystem::activeTexture(GL_TEXTURE0);
    RenderSystem::bindTexture(m_defaultTextureId);
    RenderSystem::checkGLError("after_bind_texture");

    setUniformIntInternal(m_defaultProgram, "uTexture", 0);
    setUniformVec4Internal(m_defaultProgram, "uColor", m_colliderColor);
    setUniformFloatInternal(m_defaultProgram, "uOpacity", 1.0f);
    setUniformIntInternal(m_defaultProgram, "uBlendMode", 0);
    setUniformIntInternal(m_defaultProgram, "uDebugMode", 0);
    RenderSystem::checkGLError("after_set_uniforms");

    // 使用单位矩阵作为 model（碰撞体顶点按世界坐标提供）
    setUniformMatrix3(m_defaultProgram, "uModelMatrix", Matrix3f(1.0f));
    RenderSystem::checkGLError("after_set_model_matrix");

    auto& colliders = physics->getColliders();

    if (colliders.empty()) {
        logger.debug("No colliders to render");
        return;
    }

    int enabledColliders = 0;
    for (auto& collider : colliders) {
        if (!collider->isEnabled()) continue;

        RenderSystem::checkGLError("before_render_collider_" + enabledColliders);
        if (auto* c = dynamic_cast<CircleCollider*>(collider.get())) {
            if (c->getRadius() > 0) {
                drawCircleColliderWire(c->getCenter(), c->getRadius());
                enabledColliders++;
            }
            else {
                logger.warning("Invalid CircleCollider: center={}, radius={}", c->getCenter(), c->getRadius());
            }
        }
        else if (auto* r = dynamic_cast<RectangleCollider*>(collider.get())) {
            if (r->getWidth() > 0 && r->getHeight() > 0) {
                drawRectangleColliderWire(r->getCenter(), r->getWidth(), r->getHeight());
                enabledColliders++;
            }
            else {
                logger.warning("Invalid RectangleCollider: center={}, width={}, height={}",
                    r->getCenter(), r->getWidth(), r->getHeight());
            }
        }
        else {
            logger.warning("Unknown collider type: {}", collider->getClassName());
        }

        RenderSystem::checkGLError("after_render_collider_" + enabledColliders);
    }

    logger.debug("Rendered {} enabled colliders", enabledColliders);

    // 恢复默认线宽
    RenderSystem::lineWidth(1.0f);
    RenderSystem::checkGLError("after_reset_line_width");
}

void ModelRender::drawCircleColliderWire(Vector2f center, GLfloat radius)
{
    int segments = std::max(8, m_circleSegments);

    Tesselator& tesselator = Tesselator::getInstance();
    BufferBuilder& builder = tesselator.getBuilder();

    builder.begin(GL_LINE_LOOP, segments);
    for (int i = 0; i < segments; i++) {
        double ang = 2.0 * c_pi * i / segments;
        GLfloat x = center.x + radius * std::cosf(ang);
        GLfloat y = center.y + radius * std::sinf(ang);
        builder.vertex(x, y, 0.5f, 0.5f);
    }
    tesselator.end();
}

void ModelRender::drawRectangleColliderWire(Vector2f center, GLfloat width, GLfloat height)
{
    GLfloat halfW = width / 2.0f;
    GLfloat halfH = height / 2.0f;

    Tesselator& tesselator = Tesselator::getInstance();
    BufferBuilder& builder = tesselator.getBuilder();

    builder.begin(GL_LINE_LOOP, 4);
    builder.vertex(center.x - halfW, center.y - halfH, 0.5f, 0.5f);
    builder.vertex(center.x + halfW, center.y - halfH, 0.5f, 0.5f);
    builder.vertex(center.x + halfW, center.y + halfH, 0.5f, 0.5f);
    builder.vertex(center.x - halfW, center.y + halfH, 0.5f, 0.5f);
    tesselator.end();
}

void ModelRender::setUniformIntInternal(ShaderProgram* sp, std::string name, int value)
{
    int loc = sp->getUniformLocation(name);
    if (loc != -1) RenderSystem::uniform1i(loc, value);
}

void ModelRender::setUniformVec3Internal(ShaderProgram* sp, std::string name, Vector3f vec)
{
    int loc = sp->getUniformLocation(name);
    if (loc != -1) RenderSystem::uniform3f(loc, vec);
}

void ModelRender::setUniformVec2Internal(ShaderProgram* sp, std::string name, Vector2f vec)
{
    int loc = sp->getUniformLocation(name);
    if (loc != -1) RenderSystem::uniform2f(loc, vec);
}

void ModelRender::setUniformFloatInternal(ShaderProgram* sp, std::string name, GLfloat value)
{
    int loc = sp->getUniformLocation(name);
    if (loc != -1) RenderSystem::uniform1f(loc, value);
}

void ModelRender::setUniformVec4Internal(ShaderProgram* sp, std::string name, Vector4f vec)
{
    int loc = sp->getUniformLocation(name);
    if (loc != -1) RenderSystem::uniform4f(loc, vec);
}

void ModelRender::setUniformMatrix3(ShaderProgram* sp, std::string name, Matrix3f m)
{
    int loc = sp->getUniformLocation(name);
    if (loc == -1) return;
    RenderSystem::uniformMatrix3(loc, m);
}

void ModelRender::setPartUniforms(ShaderProgram* sp, ModelPart* part)
{
    setUniformFloatInternal(sp, "uOpacity", part->getOpacity());
    int blend = 0;
    ModelPart::BlendMode bm = part->getBlendMode();
    switch (bm)
    {
    case Vivid2D::ModelPart::BlendMode::ADDITIVE:
        blend = 1;
        break;
    case Vivid2D::ModelPart::BlendMode::MULTIPLY:
        blend = 2;
        break;
    case Vivid2D::ModelPart::BlendMode::SCREEN:
        blend = 3;
        break;
    default:
    case Vivid2D::ModelPart::BlendMode::NORMAL:
        blend = 0;
        break;
    }
    setUniformIntInternal(sp, "uBlendMode", blend);
    // 这里保留为白色，若需要部件 tint 请替换为 part 的 color 属性
    setUniformVec4Internal(sp, "uColor", Vector4f(1, 1, 1, 1));
}

ModelRender::Matrix3f ModelRender::buildOrthoProjection(int width, int height)
{
    // 这个投影把屏幕像素坐标（x in [0,width], y in [0,height]）映射到 NDC [-1,1]x[1,-1]
    Matrix3f m(
        2.0f / width, 0.0f, -1.0f,
        0.0f, -2.0f / height, 1.0f,
        0.0f, 0.0f, 1.0f
    );
    return m;
}

void ModelRender::renderText(std::string text, GLfloat x, GLfloat y, Vector4f color)
{
    if (!m_isInitialized || !m_defaultTextRenderer) return;
    RenderSystem::assertOnRenderThread();
    Vector2f offset = getCameraOffset();
    GLfloat px = x - offset.x;
    GLfloat py = y - offset.y;
    m_defaultTextRenderer->renderText(text, px, py, color);
}

ModelRender::Vector2f ModelRender::getCameraOffset()
{
    GLfloat width = m_viewportSize.width;
    GLfloat height = m_viewportSize.height;
    GLfloat zoom = m_camera.getZoom();
    Vector2f pos = m_camera.getPosition();
    GLfloat tx = -1.0f - (2.0f * zoom * pos.x / width);
    GLfloat ty = 1.0f + (2.0f * zoom * pos.y / height);
    GLfloat tx0 = -1.0f;
    GLfloat ty0 = 1.0f;
    GLfloat offsetX = tx - tx0;
    GLfloat offsetY = ty - ty0;
    offsetX = -offsetX * width / 2.0f / zoom;
    offsetY = offsetY * height / 2.0f / zoom;
    return Vector2f(offsetX, offsetY);
}

void ModelRender::setViewport(int width, int height)
{
    m_viewportSize.width = std::max(1, width);
    m_viewportSize.height = std::max(1, height);
    RenderSystem::viewport(0, 0, m_viewportSize.width, m_viewportSize.height);
}
