// Vivid2D.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#ifdef VIVID_2D_MYDLL_API
#undef VIVID_2D_MYDLL_API
#endif
#define VIVID_2D_MYDLL_API __declspec(dllimport) 

#include <glm/glm.hpp>
#include <iostream>
#include <glm/vec2.hpp>
#include <systems/RenderSystem.h>
#include <glad/glad.h>
#include <systems/Buffer/BufferBuilder.h>
#include <systems/Buffer/Tesselator.h>
#include <systems/sources/ShaderManagement.h>
#include <systems/sources/ShaderProgram.h>
#include <GLFW/glfw3.h>
#include <stdexcept> 
#include <glm/gtc/matrix_transform.hpp> 
#include <glm/gtc/type_ptr.hpp> 

#ifndef M_PI
#define M_PI 3.14159265358979323846f
#endif

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    RenderSystem::viewport(0, 0, width, height);
}

int main() {
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(800, 600, "Vivid2D Circle Test", NULL, NULL);
    if (window == NULL) {
        std::cerr << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
        std::cerr << "Failed to initialize GLAD" << std::endl;
        glfwTerminate();
        return -1;
    }
    RenderSystem::InitializeLogging();

    try {
        typedef RenderSystem::GLADloader GLADloaderType;
        RenderSystem::loadGLFunctions(reinterpret_cast<GLADloaderType>(glfwGetProcAddress));
    }
    catch (const std::runtime_error& e) {
        std::cerr << "FATAL ERROR during GL function loading in DLL: " << e.what() << std::endl;
        glfwTerminate();
        return -1;
    }

    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    std::cout << "Initializing RenderSystem Logging..." << std::endl;
    RenderSystem::initRenderThread();
    RenderSystem::beginInitialization();

    RenderSystem::viewport(0, 0, 800, 600);

    // ----------------------------------------------------------------------
    // 步骤 1: 记录编译指令，但不立即执行
    // ----------------------------------------------------------------------
    std::cout << "Compiling all shaders..." << std::endl;
    RenderSystem::recordRenderCall([]() { ShaderManagement::compileAllShaders(); });

    // ----------------------------------------------------------------------
    // 步骤 2: 立即执行队列，编译着色器
    // ----------------------------------------------------------------------
    std::cout << "Executing initialization queue (Shader compilation)..." << std::endl;
    RenderSystem::replayQueue();
    std::cout << "Shader compilation executed. Queue size: " << RenderSystem::getQueueSize() << std::endl;

    // ----------------------------------------------------------------------
    // 步骤 3: 在主线程上安全地获取已编译的着色器 ID 和设置 Uniforms
    // ----------------------------------------------------------------------
    glm::mat4 projection = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f);
    glm::mat4 viewMatrix = glm::mat4(1.0f);
    glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(400.0f, 300.0f, 0.0f));
    ShaderProgram* circleProgram = ShaderManagement::getShaderProgram("Solid Color Shader");

    if (circleProgram) {

        // 记录设置 Uniforms 的指令
        RenderSystem::recordRenderCall([=]() {
            circleProgram->use();
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            // 设置 Projection Matrix (mat3)
            GLint projLoc = circleProgram->getUniformLocation("uProjectionMatrix");
            if (projLoc != -1) {
                RenderSystem::uniformMatrix3(projLoc, projection, false);
            }

            // 设置 View Matrix (mat3)
            GLint viewLoc = circleProgram->getUniformLocation("uViewMatrix");
            if (viewLoc != -1) {
                RenderSystem::uniformMatrix3(viewLoc, viewMatrix, false);
            }

            // 设置 Model Matrix (mat3)
            GLint modelLoc = circleProgram->getUniformLocation("uModelMatrix");
            if (modelLoc != -1) {
                RenderSystem::uniformMatrix3(modelLoc, modelMatrix, false);
            }

            circleProgram->stop();
            });
    }
    else {
        std::cerr << "FATAL ERROR: Solid Color Shader not found after compilation. Please check the name or compilation logs." << std::endl;
        glfwTerminate();
        return -1;
    }


    // ----------------------------------------------------------------------
    // 步骤 4: 记录绘制命令，使用已获取的 ID
    // ----------------------------------------------------------------------
    std::cout << "Recording Circle drawing command..." << std::endl;

    // ----------------------------------------------------------------------
    // 步骤 5: 执行队列，设置 Uniforms 并记录几何体到 VBO
    // ----------------------------------------------------------------------
    std::cout << "Executing final initialization queue (Uniforms and Geometry)..." << std::endl;
    RenderSystem::replayQueue(); // 再次执行队列，此时执行 Uniform 设置和绘制命令
    std::cout << "Final initialization executed. Queue size: " << RenderSystem::getQueueSize() << std::endl;

    RenderSystem::finishInitialization();

    if (RenderSystem::getQueueSize() > 0) {
        throw std::runtime_error("FATAL ERROR: Initialization failed to clear the render queue before main loop.");
    }

    std::cout << "\nStarting main render loop..." << std::endl;

    while (!glfwWindowShouldClose(window)) {

        RenderSystem::clearColor(0.2f, 0.3f, 0.3f, 1.0f);
        RenderSystem::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        Vivid2D::Render::Buffer::Tesselator& t = Vivid2D::Render::Buffer::Tesselator::getInstance();
        Vivid2D::Render::Buffer::BufferBuilder& builder = t.getBuilder();

        // 矩形的位置和大小
        const float rectX = 0; // 矩形左上角的 X 坐标
        const float rectY = 0; // 矩形左上角的 Y 坐标
        const float rectWidth = 200.0f; // 矩形宽度
        const float rectHeight = 150.0f; // 矩形高度

        // 确保深度测试被禁用，混合被启用
        RenderSystem::disableDepthTest();
        RenderSystem::enableBlend();
        RenderSystem::defaultBlendFunc();

        // 【关键修正】：设置绘制模式为实心填充
        // 如果你希望画线框，可以使用 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        RenderSystem::recordRenderCall([]() {
            glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 实心填充模式
            });


        // 【关键修正】：开始绘制矩形
        // 使用 GL_TRIANGLE_STRIP 绘制一个填充的矩形 (4个顶点)
        builder.begin(GL_TRIANGLE_STRIP, 4); // 绘制两个三角形形成一个矩形
        builder.setShader(circleProgram->getProgramId());
        builder.setColor(glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); // 红色
        builder.setTexture(0, 0); // 不需要纹理

        // 矩形的四个顶点（顺序很重要，对于 GL_TRIANGLE_STRIP）
        // 左上角 (X, Y)
        builder.vertex(rectX, rectY, 0.0f, 0.0f);
        // 右上角 (X + Width, Y)
        builder.vertex(rectX + rectWidth, rectY, 1.0f, 0.0f);
        // 左下角 (X, Y + Height)
        builder.vertex(rectX, rectY + rectHeight, 0.0f, 1.0f);
        // 右下角 (X + Width, Y + Height)
        builder.vertex(rectX + rectWidth, rectY + rectHeight, 1.0f, 1.0f);

        t.end();

        // 确保 GL 状态记录被执行
        RenderSystem::replayQueue();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }   

    std::cout << "\nShutting down RenderSystem Logging." << std::endl;
    RenderSystem::recordRenderCall([]() { ShaderManagement::cleanup(); });
    RenderSystem::replayQueue();
    RenderSystem::ShutdownLogging();
    return 0;
}