#include <Core/Common/String.h>
#include <Core/Memory/EngineArena.h>
#include <cstdio>
#include <Engine/Debug/MemoryDebugger.h>
#include <imgui.h>

namespace Juliet::Debug
{
    namespace
    {
        void DrawMemoryArena(String name, const MemoryArena& arena)
        {
            if (ImGui::CollapsingHeader(CStr(name), ImGuiTreeNodeFlags_DefaultOpen))
            {
                float progress = 0.0f;
                if (arena.Size > 0)
                {
                    progress = (float)arena.Offset / (float)arena.Size;
                }

                char overlay[64];
                sprintf_s(overlay, "%zu / %zu bytes", arena.Offset, arena.Size);
                ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f), overlay);

#if JULIET_DEBUG
                ImGui::PushID(CStr(name));
                if (ImGui::TreeNode("Allocations"))
                {
                    size_t displayedSize = 0;
                    // Draw allocations as a list for now
                    if (ImGui::BeginTable("AllocationsTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable))
                    {
                        ImGui::TableSetupColumn("Tag");
                        ImGui::TableSetupColumn("Size");
                        ImGui::TableSetupColumn("Offset");
                        ImGui::TableHeadersRow();

                        for (size_t i = 0; i < arena.AllocationCount; ++i)
                        {
                            const auto& alloc = arena.Allocations[i];
                            ImGui::TableNextRow();
                            ImGui::TableSetColumnIndex(0);
                            ImGui::Text("%s", CStr(alloc.Tag));
                            ImGui::TableSetColumnIndex(1);
                            ImGui::Text("%zu", alloc.Size);
                            ImGui::TableSetColumnIndex(2);
                            ImGui::Text("%zu", alloc.Offset);

                            displayedSize += alloc.Size;
                        }
                        ImGui::EndTable();
                    }
                    ImGui::Text("Total Tracked Size: %zu", displayedSize);
                    ImGui::Text("Untracked/Padding: %zu", arena.Offset - displayedSize);

                    ImGui::TreePop();
                }
                ImGui::PopID();
#else
                ImGui::Text("Detailed allocation tracking disabled in Release build.");
#endif
            }
        }
    } // namespace

    void DebugDrawMemoryArena()
    {
        if (ImGui::Begin("Memory Debugger"))
        {
            DrawMemoryArena(ConstString("Game Arena"), *GetGameArena());
            DrawMemoryArena(ConstString("Engine Arena"), *GetEngineArena());
            DrawMemoryArena(ConstString("Scratch Arena"), *GetScratchArena());
        }
        ImGui::End();
    }
} // namespace Juliet::Debug
