local current_preview = nil


local search_query = ""
local last_search_query = ""
local search_cache = {}
local debounce_timer = 0


function directory_contains_matching_files(path)
    if search_cache[path] ~= nil then
        return search_cache[path]
    end

    local idx = 0
    local contains_matches = false
    while true do
        local file = reaper.EnumerateFiles(path, idx)
        if not file then break end

     
        if not file:match("^%.") then
        
            if (file:match("%.wav$") or file:match("%.mp3$")) and (search_query == "" or file:lower():find(search_query:lower(), 1, true)) then
                contains_matches = true
                break
            end
        end

        idx = idx + 1
    end

    if not contains_matches then
        idx = 0
        while true do
            local subdir = reaper.EnumerateSubdirectories(path, idx)
            if not subdir then break end

      
            if not subdir:match("^%.") then
                local full_path = path .. "/" .. subdir
                if directory_contains_matching_files(full_path) then
                    contains_matches = true
                    break
                end
            end

            idx = idx + 1
        end
    end

    search_cache[path] = contains_matches
    return contains_matches
end

function create_directory_tree(path, depth)
    if depth > 5 then return end  


    local idx = 0
    while true do
        local subdir = reaper.EnumerateSubdirectories(path, idx)
        if not subdir then break end

        
        if not subdir:match("^%.") then
            local full_path = path .. "/" .. subdir

            if directory_contains_matching_files(full_path) then
                if reaper.ImGui_TreeNode(ctx, subdir) then
                    create_directory_tree(full_path, depth + 1)
                    reaper.ImGui_TreePop(ctx)
                end
            end
        end

        idx = idx + 1
    end


    idx = 0
    while true do
        local file = reaper.EnumerateFiles(path, idx)
        if not file then break end

   
        if not file:match("^%.") then
         
            if (file:match("%.wav$") or file:match("%.mp3$")) and (search_query == "" or file:lower():find(search_query:lower(), 1, true)) then
                if reaper.ImGui_Selectable(ctx, file) then
         
                    preview_file(path .. "/" .. file)
                end
            end
        end

        idx = idx + 1
    end
end


function preview_file(file)
  
    if current_preview then
        reaper.CF_Preview_StopAll()
        current_preview = nil
    end

    local source = reaper.PCM_Source_CreateFromFile(file)

  
    current_preview = reaper.CF_CreatePreview(source)


    local play_success = reaper.CF_Preview_Play(current_preview)
    if not play_success then
        reaper.ShowMessageBox("Failed to play preview: " .. file, "Error", 0)
    end
end

function main()
    reaper.ImGui_SetNextWindowDockID(ctx, -7)
    local retval, is_open = reaper.ImGui_Begin(ctx, "Media Explorer", true)

    if is_open then
    
        local changed, text = reaper.ImGui_InputText(ctx, "Search", search_query, 256)
        if changed then
            search_query = text
            debounce_timer = reaper.time_precise() + 0.3  
        end

        if reaper.time_precise() > debounce_timer then
            if search_query ~= last_search_query then
                search_cache = {}  
                last_search_query = search_query
            end

          
            create_directory_tree("E:\\Sample Packs\\COLLECTION", 0)
        end

        reaper.defer(main)
    end

    reaper.ImGui_End(ctx)
end

ctx = reaper.ImGui_CreateContext("ctx")
main()