#include "AssetBrowser.h"
#include <imgui.h>
#include "../../core/utils/EngineConfig.h"
#include "../../core/utils/utils.h"
#include "../../core/utils/AssetManager.h"
#include "../../Renderer.h"
#include "../../core/utils/Logging.h"
#include "../../core/utils/LoadingWindow.h"

static std::string assetSearchQuery;
static bool sortAscending = true;
static int sortMode = 0; // 0 = Name, 1 = Type, 2 = UAID
static bool showImages = true;
static bool showAudio = true;

void ShowAssetBrowser()
{
    PROFILE_ENGINE_SCOPE("Editor::AssetBrowser");

    if (!g_engineConfig.settings.show_asset_window)
        return;

    ImGui::Begin("Resources");

    // Top bar layout
    ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(6, 4));
    ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(8, 6));

    // Load Buttons
    if (ImGui::Button("Load Images"))
    {
        std::vector<std::string> paths = OpenMultipleFilesDialog(FileDialogType::Images);
        if (!paths.empty())
        {
            LoadingWindow loader;
            loader.Create("Loading Images...");

            for (size_t i = 0; i < paths.size(); ++i)
            {
                const std::string &path = paths[i];
                loader.Update("Loading Image", path, static_cast<float>(i + 1) / paths.size());
                AssetManager::LoadAssetAsync(path, AssetType::Image);
            }

            loader.Destroy();
        }
    }

    ImGui::SameLine();

    if (ImGui::Button("Load Audio"))
    {
        std::vector<std::string> paths = OpenMultipleFilesDialog(FileDialogType::Audio);
        if (!paths.empty())
        {
            LoadingWindow loader;
            loader.Create("Loading Audio...");

            for (size_t i = 0; i < paths.size(); ++i)
            {
                const std::string &path = paths[i];
                loader.Update("Loading Audio", path, static_cast<float>(i + 1) / paths.size());
                AssetManager::LoadAssetAsync(path, AssetType::Audio);
            }

            loader.Destroy();
        }
    }

    ImGui::SameLine();

    if (ImGui::Button("Filters / Sort"))
        ImGui::OpenPopup("AssetBrowserFilterPopup");

    // Filters Popup
    if (ImGui::BeginPopup("AssetBrowserFilterPopup"))
    {
        ImGui::Text("Sort By:");
        if (ImGui::Selectable("Name", sortMode == 0))
            sortMode = 0;
        if (ImGui::Selectable("Type", sortMode == 1))
            sortMode = 1;
        if (ImGui::Selectable("UAID", sortMode == 2))
            sortMode = 2;

        ImGui::Checkbox("Ascending", &sortAscending);

        ImGui::Separator();
        ImGui::Text("Type Filters:");
        ImGui::Checkbox("Images", &showImages);
        ImGui::Checkbox("Audio", &showAudio);

        ImGui::EndPopup();
    }

    ImGui::PopStyleVar(2);

    // Search field (spaced below buttons)
    ImGui::Spacing();
    ImGui::Spacing();

    char buffer[256] = {};
    strncpy(buffer, assetSearchQuery.c_str(), sizeof(buffer) - 1);
    ImGui::SetNextItemWidth(-1);
    if (ImGui::InputTextWithHint("##Search", "Search", buffer, sizeof(buffer)))
    {
        assetSearchQuery = buffer;
    }

    

    ImGui::Separator();
    ImGui::BeginChild("##AssetScroll", ImVec2(0, 0), true);

    const float padding = 8.0f;
    const float thumbnailSize = 64.0f;
    const float cellSize = thumbnailSize + padding;

    float availWidth = ImGui::GetContentRegionAvail().x;
    int columns = static_cast<int>(availWidth / cellSize);
    if (columns < 1)
        columns = 1;

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

    // Collect, filter and sort assets
    std::vector<const AssetInfo *> sortedAssets;
    for (const auto &[uaid, asset] : AssetManager::GetAllAssets())
    {
        if (!asset || !asset->loaded)
            continue;

        if (!assetSearchQuery.empty() &&
            asset->filename.find(assetSearchQuery) == std::string::npos &&
            asset->path.find(assetSearchQuery) == std::string::npos)
            continue;

        if ((asset->type == AssetType::Image && !showImages) ||
            (asset->type == AssetType::Audio && !showAudio))
            continue;

        sortedAssets.push_back(asset.get());
    }

    std::sort(sortedAssets.begin(), sortedAssets.end(), [](const AssetInfo *a, const AssetInfo *b)
              {
        switch (sortMode)
        {
            case 0: return sortAscending ? a->filename < b->filename : a->filename > b->filename;
            case 1: return sortAscending ? a->type < b->type : a->type > b->type;
            case 2: return sortAscending ? a->uaid < b->uaid : a->uaid > b->uaid;
            default: return true;
        } });

    int idx = 0;
    for (const AssetInfo *baseAsset : sortedAssets)
    {
        ImGui::PushID(idx++);
        std::string displayName = GetFilenameFromPath(baseAsset->path);

        if (baseAsset->type == AssetType::Image)
        {
            const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset);
            if (!imageAsset)
            {
                ImGui::PopID();
                continue;
            }

            ImGui::Image((ImTextureID)(intptr_t)imageAsset->textureID,
                         ImVec2(thumbnailSize, thumbnailSize));

            if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
            {
                ImGui::SetDragDropPayload("ASSET_TEXTURE", &baseAsset->uaid, sizeof(uint64_t));
                ImGui::Text("%s", displayName.c_str());
                ImGui::EndDragDropSource();
            }
        }
        else if (baseAsset->type == AssetType::Audio)
        {
            std::string buttonLabel = baseAsset->filetype.empty() ? "Audio" : baseAsset->filetype;
            ImGui::Button(buttonLabel.c_str(), ImVec2(thumbnailSize, thumbnailSize));

            if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
            {
                ImGui::SetDragDropPayload("ASSET_AUDIO", &baseAsset->uaid, sizeof(uint64_t));
                ImGui::Text("%s", displayName.c_str());
                ImGui::EndDragDropSource();
            }
        }
        else
        {
            ImGui::PopID();
            continue;
        }

        if (ImGui::IsItemHovered())
        {
            ImGui::BeginTooltip();
            ImGui::Text("Path: %s", baseAsset->path.c_str());
            ImGui::Text("UAID: %llu", baseAsset->uaid);

            if (baseAsset->type == AssetType::Image)
            {
                const auto *imageAsset = dynamic_cast<const ImageAssetInfo *>(baseAsset);
                if (imageAsset)
                {
                    ImGui::Text("Texture ID: %u", imageAsset->textureID);
                    ImGui::Text("Size: (%.0f, %.0f)", imageAsset->size.x, imageAsset->size.y);
                }
            }
            else if (baseAsset->type == AssetType::Audio)
            {
                ImGui::Text("Audio file");
            }

            ImGui::EndTooltip();
        }

        if (ImGui::BeginPopupContextItem("AssetContext"))
        {
            if (ImGui::MenuItem("Unload"))
            {
                Logger::LogInfo("[AssetBrowser] Unloaded: %s", baseAsset->path.c_str());
                AssetManager::UnloadAsset(baseAsset->uaid);
                ImGui::EndPopup();
                ImGui::PopID();
                continue;
            }

            if (ImGui::MenuItem("Copy Path"))
            {
                ImGui::SetClipboardText(baseAsset->path.c_str());
            }

            if (ImGui::MenuItem("Copy UAID"))
            {
                ImGui::SetClipboardText(std::to_string(baseAsset->uaid).c_str());
            }

            ImGui::EndPopup();
        }

        ImGui::TextWrapped("%s", displayName.c_str());
        ImGui::NextColumn();
        ImGui::PopID();
    }

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