rewrite this code to store the data in a std container like std::map instead of qjsonobject
do not emit anything like "... continues the same"

pay attention to not try to write wrong things like

using bla = std::map<.......,   bla>  <- bla is undefined




struct EnumFilesConfig
{
    int  maxNestLevel = 0;
    std::unordered_map<int, int> maxItemsPerLevel;
    bool captureFoldersOnly = false;
    int  currentLevel       = 0;
};

template <typename T>
void enumFiles(const T& t, QJsonObject& jsonObject, EnumFilesConfig config = {})
{
    HRESULT hr                = S_FALSE;
    CComPtr<IShellItem> pItem = NULL;

    if constexpr (std::is_same_v<T, GUID>) // FOLDERID_Desktop, FOLDERID_Documents, FOLDERID_Downloads etc
        hr = SHCreateItemInKnownFolder(t, KF_FLAG_DEFAULT, nullptr, IID_PPV_ARGS(&pItem));
    else if constexpr (std::is_same_v<T, QString>)
        hr = SHCreateItemFromParsingName(t.toStdWString().c_str(), nullptr, IID_PPV_ARGS(&pItem));
    else if constexpr (std::is_array_v<T> || std::is_same_v<T, wchar_t*>)
        hr = SHCreateItemFromParsingName(t, nullptr, IID_PPV_ARGS(&pItem));
    if (hr != S_OK || !pItem)
        return;



    const auto getFileProperty = [](CComPtr<IPropertyStore> pPropertyStore, const PROPERTYKEY& key) -> QByteArray
    {
        PROPVARIANT propvar;
        PropVariantInit(&propvar);
        HRESULT hr = pPropertyStore->GetValue(key, &propvar);
        if (FAILED(hr))
        {
            PropVariantClear(&propvar);
            return "";
        }

        QString result;
        switch (propvar.vt)
        {
            case VT_LPWSTR:  // Wide string (pointer to a wide string)
            if (propvar.pwszVal != NULL)
                result = QString::fromWCharArray(propvar.pwszVal);
            break;
    
            case VT_BSTR:  // Binary string
            if (propvar.bstrVal != NULL)
                result = QString::fromWCharArray(propvar.bstrVal);
            break;
    
            case VT_UI4:  // Unsigned 32-bit integer
            result = QString::number(propvar.ulVal);
            break;
    
            case VT_UI8:  // Unsigned 64-bit integer
            result = QString::number(propvar.uhVal.QuadPart);
            break;
    
            case VT_I4:  // Signed 32-bit integer
            result = QString::number(propvar.lVal);
            break;
    
            case VT_I8:  // Signed 64-bit integer
            result = QString::number(propvar.hVal.QuadPart);
            break;
       
            default: break;
        }

        PropVariantClear(&propvar);

        QByteArray data(result.toUtf8());
        if (result.isEmpty())
            return data;

        return data;
    };
    
    const auto getProperties   = [=](CComPtr<IShellItem> pItem) -> QJsonArray
    {
        CComPtr<IPropertyStore> pPropertyStore;
        if (FAILED(pItem->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&pPropertyStore))))
        {
            CComPtr<IPropertyStoreFactory> factory;
            HRESULT hr = pItem->BindToHandler(nullptr, BHID_PropertyStore, IID_PPV_ARGS(&factory));
            if (FAILED(hr))
                return QJsonArray();
            hr = factory->GetPropertyStore(GPS_BESTEFFORT, nullptr, IID_PPV_ARGS(&pPropertyStore));
            if (FAILED(hr))
                return QJsonArray();
        }
        if (!pPropertyStore)
			return QJsonArray();

        PROPVARIANT propvar;
        PropVariantInit(&propvar);
        HRESULT hr = pPropertyStore->GetValue(PKEY_PerceivedType, &propvar);
        if (FAILED(hr))
        {
            PropVariantClear(&propvar);
            return QJsonArray();
        }

        bool isImage = (propvar.lVal >= 2 && propvar.lVal <= 4);
        RtlSecureZeroMemory(&propvar, sizeof(propvar));
        PropVariantClear(&propvar);

        // https://learn.microsoft.com/en-us/windows/win32/properties/props-system-perceivedtype
        if (isImage)
            return QJsonArray(); // dont take properties for: images, audio, video

        PROPERTYKEY PKEY_ProductVersion;
        PSGetPropertyKeyFromName(L"System.Software.ProductVersion", &PKEY_ProductVersion);

        QJsonArray jsonArray;
		for (const auto& key : { PKEY_Size,                 PKEY_FileDescription,  PKEY_FileVersion, PKEY_ProductVersion,
                                 PKEY_Software_ProductName, PKEY_OriginalFileName, PKEY_Company,     PKEY_Copyright })
		{
            QByteArray data = getFileProperty(pPropertyStore, key);
            jsonArray.append(data.isEmpty() ? 0 : data.data());
		}

        return jsonArray;
    };



    DWORD attributes = 0;
    hr = pItem->GetAttributes(SFGAO_STORAGE | SFGAO_FOLDER | SFGAO_LINK, &attributes);
    if (attributes & SFGAO_LINK) // shortcut (.lnk)
    {
        CComPtr<IShellLink> shellLink;
        HRESULT hr = pItem->BindToHandler(NULL, BHID_SFObject, IID_PPV_ARGS(&shellLink));
        if (!shellLink)
            return;
        hr = shellLink->Resolve(NULL, SLR_NO_UI);
        if (FAILED(hr))
            return;        
        WCHAR path[MAX_PATH];
        hr = shellLink->GetPath(path, MAX_PATH, NULL, SLGP_RAWPATH);
        if (SUCCEEDED(hr) && path[0])
        {
            config.currentLevel++;
            if (config.currentLevel <= config.maxNestLevel)
                enumFiles(path, jsonObject, config);
        }
        return;
    }



    CComHeapPtr<wchar_t> displayName;
    bool isFolder = ((attributes & SFGAO_FOLDER) && (attributes & SFGAO_STORAGE));
    pItem->GetDisplayName(isFolder ? SIGDN_FILESYSPATH : SIGDN_NORMALDISPLAY, &displayName);
    if (displayName.m_pData == NULL || !displayName.m_pData[0])
        return;

    QString string = QString::fromWCharArray(displayName.m_pData);
    QByteArray file(string.toUtf8());

    if (isFolder)
    {
        if (enumFilesDuplicateTracker.hasSeenL(file))
        {
			file.prepend("[D]"); // mark as duplicate
            jsonObject.insert(file, QJsonObject());
            return; // already parsed this folder
        }

        wEncrypt(file);
        auto it = jsonObject.insert(file, QJsonObject());
        QCLEAR(file)

        CComPtr<IEnumShellItems> items;
        CComPtr<IPropertyBag> bag;
        CComPtr<IBindCtx> ctx;
        PSCreateMemoryPropertyStore(IID_PPV_ARGS(&bag));
        CreateBindCtx(0, &ctx);
        if (bag && ctx)
        {
            ctx->RegisterObjectParam((LPOLESTR)STR_PROPERTYBAG_PARAM, bag);
            ATL::CComVariant flags = CComVariant(SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN | SHCONTF_NONFOLDERS);
            bag->Write(STR_ENUM_ITEMS_FLAGS, &flags);
        }

        hr = pItem->BindToHandler(ctx, BHID_EnumItems, IID_PPV_ARGS(&items));
        if (FAILED(hr) || !items)
            return;

        QJsonObject folderObject;
        int maxItems = config.maxItemsPerLevel[config.currentLevel];
        if (!maxItems)
			maxItems = 100; // Default to 100 if not specified
        
        int itemCount = 0;
        do
        {
            CComPtr<IShellItem> pChildItem;
            if (itemCount >= maxItems || items->Next(1, &pChildItem, nullptr) != S_OK)
                break;

            if (config.currentLevel < config.maxNestLevel)
            {
                CComHeapPtr<wchar_t> name;
                pChildItem->GetDisplayName(SIGDN_FILESYSPATH, &name);
                if (name.m_pData == NULL || !name.m_pData[0])
                    continue;

                EnumFilesConfig newConfig = config;
                newConfig.currentLevel++;
                enumFiles(name.m_pData, folderObject, newConfig);
            }
            else
            {               
                attributes = 0;
                hr = pChildItem->GetAttributes(SFGAO_FOLDER, &attributes);
                bool isFolder = (FAILED(hr) || (attributes & SFGAO_FOLDER));

                CComHeapPtr<wchar_t> name;
                pChildItem->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
                if (!name.m_pData || !name.m_pData[0])
                    continue;

                QString string = QString::fromWCharArray(name);
                QByteArray file(string.toUtf8());

                if (isFolder)
                    folderObject[file]; // not necessary to get properties for folders
                else if (!config.captureFoldersOnly)
                    folderObject[file] = getProperties(pChildItem);
            }
            
            itemCount++;
        } while (true);

        it.value() = folderObject;
    }
    else if (!config.captureFoldersOnly) // its a file and the option to get only folders is not set
        jsonObject[file] = getProperties(pItem);

}