#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"

static std::string assetSearchQuery;

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

    if (!g_engineConfig.settings.show_asset_window)
        return;

    ImGui::Begin("Asset Browser");

    if (ImGui::Button("Load Image"))
    {
        std::string path = OpenFileDialog(FileDialogType::Images);
        if (!path.empty())
            AssetManager::LoadAssetAsync(path, AssetType::Image);
    }

    ImGui::SameLine();

    if (ImGui::Button("Load Audio"))
    {
        std::string path = OpenFileDialog(FileDialogType::Audio);
        if (!path.empty())
            AssetManager::LoadAssetAsync(path, AssetType::Audio);
    }

    ImGui::Separator();
    char buffer[256] = {};
    strncpy(buffer, assetSearchQuery.c_str(), sizeof(buffer) - 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);

    int idx = 0;
    for (const auto &[uaid, baseAsset] : AssetManager::GetAllAssets())
    {
        if (!baseAsset || !baseAsset->loaded)
            continue;

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

        ImGui::PushID(idx++);
        std::string displayName = GetFilenameFromPath(baseAsset->path);

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

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

            if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_SourceAllowNullID))
            {
                ImGui::SetDragDropPayload("ASSET_TEXTURE", &uaid, sizeof(uint64_t));
                ImGui::Image((ImTextureID)(intptr_t)imageAsset->textureID,
                             ImVec2(thumbnailSize * 2, thumbnailSize * 2));
                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", &uaid, sizeof(uint64_t));
                ImGui::Text("Audio: %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.get());
                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(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();
}
