//
// Created by spenc on 5/18/2025.
//

#include "Editor.h"
#include <functional>
#include <imgui.h>
#include <imgui_impl_opengl3.h>
#include <imgui_impl_glfw.h>

#include "Windows/LoggerWindow.h"
#include "Windows/Viewport.h"

namespace OX {

    void Editor::Init(Core& core)
    {
        Logger::LogInfo("%s Init", m_name.c_str());

        IMGUI_CHECKVERSION();
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO();

        io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
        io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;

        ImGui::StyleColorsDark();

        ImGuiStyle& style = ImGui::GetStyle();
        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) {
            style.WindowRounding = 5.0f;
            style.Colors[ImGuiCol_WindowBg].w = 1.0f;
        }

        ImGui_ImplGlfw_InitForOpenGL(core.GetWindow().GetHandle(), true);
        ImGui_ImplOpenGL3_Init("#version 330 core");

        primaryViewport = new Viewport(); // The first time ive ever use the new keywork...
    }

    void Editor::Update(Core& core)
    {
        OX_PROFILE_FUNCTION();

    }

    void Editor::Draw(Core& core)
    {

        OX_PROFILE_FUNCTION();


        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();



        // === Main Docking Space ===
        ImGuiWindowFlags windowFlags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoBackground;

        const ImGuiViewport* viewport = ImGui::GetMainViewport();
        ImGui::SetNextWindowPos(viewport->WorkPos);
        ImGui::SetNextWindowSize(viewport->WorkSize);
        ImGui::SetNextWindowViewport(viewport->ID);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
        ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
        ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
        windowFlags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
        windowFlags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;

        ImGui::Begin("DockSpace Root", nullptr, windowFlags);
        ImGui::PopStyleVar(3);

        ImGuiID dockspaceID = ImGui::GetID("MyDockSpace");
        ImGui::DockSpace(dockspaceID, ImVec2(0.0f, 0.0f), ImGuiDockNodeFlags_PassthruCentralNode);

        LoggerWindow::Draw();
        primaryViewport->Draw(core);


        ImGui::Begin("Profiler");

        const auto& tree = Profiler::GetSavedTree();
        if (tree.empty()) {
            ImGui::Text("No samples yet.");
        } else {
            std::function<void(const Profiler::SavedSample&, int)> DrawNode;
            DrawNode = [&](const Profiler::SavedSample& node, int depth) {
                // Indentation
                ImGui::Indent(depth * 10.0f);

                // Color based on time
                ImVec4 color;
                if (node.totalTime > 10.0f)       color = ImVec4(1.0f, 0.2f, 0.2f, 1.0f); // red
                else if (node.totalTime > 5.0f)   color = ImVec4(1.0f, 0.5f, 0.0f, 1.0f); // orange
                else if (node.totalTime > 1.0f)   color = ImVec4(1.0f, 1.0f, 0.0f, 1.0f); // yellow
                else                              color = ImVec4(0.2f, 1.0f, 0.2f, 1.0f); // green

                ImGui::PushStyleColor(ImGuiCol_Text, color);

                ImGui::Text("%s (%d): %.2f ms", node.name.c_str(), node.callCount, node.totalTime);

                ImGui::PopStyleColor();
                for (const auto& child : node.children) {
                    DrawNode(child, depth + 1);
                }

                ImGui::Unindent(depth * 10.0f);
            };

            for (const auto& root : tree) {
                DrawNode(root, 0);
            }
        }

        ImGui::End();

        ImGui::End(); // DockSpace Root

        // --- Render ImGui onto FBO 0 ---
        {
            OX_PROFILE_LABEL("VSYNC Wait");

            ImGui::EndFrame();
            ImGui::Render();
            ImGui::UpdatePlatformWindows();
            ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
        }

    }

    void Editor::Shutdown(Core& core)
    {

        delete primaryViewport;
        primaryViewport = nullptr;


        Logger::LogOk("Editor::Shutdown");
        ImGui_ImplOpenGL3_Shutdown();
        ImGui_ImplGlfw_Shutdown();
        ImGui::DestroyContext();


    }

} // OX