// File: src/FileBrowser.cpp
#include "FileBrowser.h"
#include <filesystem>
#include "systems/Profiler.h"

namespace OX
{
    FileBrowser::FileBrowser()
        : _lastProgress(0.0f)
    {
        Logger::LogVerbose("Editor::InspectorWindow");
    }

    FileBrowser::~FileBrowser() = default;

    // Call this every frame to report your current loading progress (0.0 → 1.0).
    // Passing in 0 resets it and hides the bar.
    void FileBrowser::SetProgress(const float p)
    {
        if (p <= 0.0f) {
            _lastProgress = 0.0f;
        } else {
            _lastProgress = std::max(_lastProgress, p);
        }
    }

    void FileBrowser::SetFilter(const std::string &f) { _filter = f; }
    void FileBrowser::SetFileSelectedCallback(FileSelectedCallback cb) { _onFileSelected = std::move(cb); }

    void FileBrowser::Draw(const char *title)
    {
        OX_PROFILE_FUNCTION();


        ImGui::Begin(title);

        DrawToolbar();

        // ——— main content ———
        auto root = AssetManager::GetFileTree();
        std::function<std::shared_ptr<ResourceTreeNode>(std::shared_ptr<ResourceTreeNode>, const std::string &)> find =
                [&](auto node, const std::string &path) -> std::shared_ptr<ResourceTreeNode>
        {
            if (node->path == path)
                return node;
            for (auto &c: node->children)
                if (c->isDirectory)
                    if (auto f = find(c, path))
                        return f;
            return nullptr;
        };

        auto node = find(root, _currentPath);
        if (!node) {
            ImGui::TextColored(ImGui::GetStyle().Colors[ImGuiCol_TextDisabled],
                               "Path not found: %s", _currentPath.c_str());
        } else if (_gridMode) {
            // ——— Grid view with nicer spacing ———
            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(_cfg.padding, _cfg.padding));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(_cfg.padding, _cfg.padding));
            DrawGridView(node);
            ImGui::PopStyleVar(2);
        } else {
            DrawListView(node);
        }

        ImGui::End();
    }

    // ——— Combined toolbar & inline path ———
    void FileBrowser::DrawToolbar()
    {
        if (_currentPath != "res://") {
            if (ImGui::Button("Back")) {
                auto pos = _currentPath.find_last_of('/');
                _currentPath = (pos != std::string::npos && pos > 6)
                                   ? _currentPath.substr(0, pos)
                                   : "res://";
            }
            ImGui::SameLine();
        }

        ImGui::Text("%s", _currentPath.c_str());
        ImGui::SameLine();

        float avail = ImGui::GetContentRegionAvail().x;
        ImGui::PushItemWidth(avail * 0.5f);
        //ImGui::InputTextWithHint("##filter", "Filter files...", &_filter);
        ImGui::PopItemWidth();
        ImGui::SameLine();

        if (_gridMode) {
            if (ImGui::Button("List View")) _gridMode = false;
        } else {
            if (ImGui::Button("Grid View")) _gridMode = true;
        }
        ImGui::SameLine();
        if (ImGui::Button("Rescan")) {
            AssetManager::Rescan();
        }

        size_t total = AssetManager::GetTotalTexturesToLoad();
        size_t loaded = AssetManager::GetLoadedTexturesCount();

        if (total > 0 && loaded < total) {
            float progress = float(loaded) / float(total);
            ImGui::SameLine();
            ImGui::ProgressBar(progress, ImVec2(-1, 0));
        }


        ImGui::Separator();
    }

    // ——— Polished grid view ———
    void FileBrowser::DrawGridView(const std::shared_ptr<ResourceTreeNode> &node)
    {
        OX_PROFILE_FUNCTION();

        const float cellW = _cfg.thumbnailSize + _cfg.padding * 2;
        ImVec2 avail = ImGui::GetContentRegionAvail();
        int cols = std::max(1, int(avail.x / cellW));

        // Add a little padding around the child region
        ImGui::BeginChild("GridRegion",
                          ImVec2(0, 0),
                          false,
                          ImGuiWindowFlags_AlwaysUseWindowPadding);

        ImGui::Columns(cols, nullptr, false);

        std::vector<std::shared_ptr<ResourceTreeNode> > children; {
            std::lock_guard<std::mutex> lock(AssetManager::s_TreeMutex);
            children = node->children;
        }

        for (auto &c: children) {
            if (!c) continue;
            if (!_filter.empty() && !PassesFilter(c->name)) continue;

            ImGui::PushID(c->path.c_str());
            ImGui::BeginGroup();

            ImVec2 btnSize(cellW, _cfg.thumbnailSize + _cfg.labelHeight + _cfg.padding);
            ImGui::InvisibleButton("cell", btnSize);
            bool hovered = ImGui::IsItemHovered();
            bool clicked = ImGui::IsItemClicked();

            // background
            ImVec2 mn = ImGui::GetItemRectMin();
            ImVec2 mx = ImGui::GetItemRectMax();
            ImU32 bg = hovered ? _cfg.highlightColor : _cfg.bgColor;
            ImGui::GetWindowDrawList()
                    ->AddRectFilled(mn, mx, bg, 4.0f);

            // thumbnail
            ImGui::SetCursorScreenPos({mn.x + _cfg.padding, mn.y + _cfg.padding});
            if (c->isDirectory) {
                ImGui::Image(GetIconTexture(*c),
                             {_cfg.thumbnailSize, _cfg.thumbnailSize});
            } else {
                auto asset = AssetManager::Get(c->path);
                if (asset && asset->GetTypeName() == "texture2D") {
                    auto tex = std::static_pointer_cast<Texture2D>(asset);
                    ImGui::Image((ImTextureID) (intptr_t) tex->GetID(),
                                 {_cfg.thumbnailSize, _cfg.thumbnailSize},
                                 {0, 1}, {1, 0});
                } else {
                    ImGui::Dummy({_cfg.thumbnailSize, _cfg.thumbnailSize});
                }
            }

            // label
            ImGui::SetCursorScreenPos({mn.x + _cfg.padding, mx.y - _cfg.labelHeight});
            ImGui::PushTextWrapPos(mx.x);
            ImGui::TextUnformatted(c->name.c_str());
            ImGui::PopTextWrapPos();

            // click handling
            if (clicked) {
                if (c->isDirectory)
                    _currentPath = c->path;
                else if (_onFileSelected)
                    _onFileSelected(c->path);
            }

            ImGui::EndGroup();
            ImGui::NextColumn();
            ImGui::PopID();
        }

        ImGui::Columns(1);
        ImGui::EndChild();
    }

    // ——— Simple list view ———
    void FileBrowser::DrawListView(const std::shared_ptr<ResourceTreeNode> &node)
    {
        ImGui::BeginChild("ListRegion", ImVec2(0, 0), false);

        for (auto &c: node->children) {
            if (!_filter.empty() && !PassesFilter(c->name)) continue;
            if (ImGui::Selectable(c->name.c_str(), false, ImGuiSelectableFlags_AllowDoubleClick)) {
                if (ImGui::IsMouseDoubleClicked(0)) {
                    if (c->isDirectory)
                        _currentPath = c->path;
                    else if (_onFileSelected)
                        _onFileSelected(c->path);
                }
            }
        }

        ImGui::EndChild();
    }

    bool FileBrowser::PassesFilter(const std::string &name) const
    {
        return _filter.empty() || (name.find(_filter) != std::string::npos);
    }

    ImTextureID FileBrowser::GetIconTexture(const ResourceTreeNode &node)
    {
        return 0;
    }
} // namespace OX
