function changeH5LabelsByIDV2(folderName, ids, labels, useMonitorCaseIDs)
% NOTE: V2-only implementation for H5 files using /Sensors/<ID>/Configuration.
%CHANGEH5LABELSBYID Update monitor labels by sensor ID in H5 files.
%
%   This version is compatible with files that store sensors as:
%       /Sensors/<ID>/Configuration
%   where Label 0 and Label 1 are attributes on each Configuration group.
%
%   It writes:
%   - /Sensors/<ID>/Configuration : 'Label 0'  (mixed case label)
%   - /Sensors/<ID>/Configuration : 'Label 1'  (upper(Label 0))
%   - /                        : 'MonitorLabelList' (cell array in sensor order)
%
%   Optional filter:
%   - useMonitorCaseIDs : cell array/string of IDs to update. If empty,
%     all sensors are processed.
%
%   Example:
%   changeH5LabelsByIDV2('/Users/mahmoud/Downloads', ...
%       {'1250','1307'}, {'Left Foot','Right Foot'}, {'1250'});

    if nargin < 1 || isempty(folderName)
        folderName = '/Users/mahmoud/Downloads';
    end
    if nargin < 2 || isempty(ids)
        ids = {};
    end
    if nargin < 3 || isempty(labels)
        labels = {};
    end
    if nargin < 4 || isempty(useMonitorCaseIDs)
        useMonitorCaseIDs = {};
    end

    if ischar(useMonitorCaseIDs)
        useMonitorCaseIDs = {useMonitorCaseIDs};
    elseif isstring(useMonitorCaseIDs)
        useMonitorCaseIDs = cellstr(useMonitorCaseIDs);
    end

    if numel(ids) ~= numel(labels)
        error('ids and labels must have the same number of entries.');
    end

    fileNames = dir(fullfile(folderName, '*.h5'));
    if isempty(fileNames)
        error('No .h5 files found at: %s', folderName);
    end

    for iFile = 1:numel(fileNames)
        fileName = fullfile(folderName, fileNames(iFile).name);

        try
            sensorsInfo = h5info(fileName, '/Sensors');
            groups = sensorsInfo.Groups;

            if isempty(groups)
                warning('No sensor groups found in file: %s', fileName);
                continue;
            end

            newLabelList = cell(1, numel(groups));

            for iMonitor = 1:numel(groups)
                sensorGroupPath = groups(iMonitor).Name;
                cfgPath = [sensorGroupPath '/Configuration'];
                monitorID = getLastPathToken(sensorGroupPath);

                currentLabel = '';
                try
                    currentLabel = normalizeLabel(h5readatt(fileName, cfgPath, 'Label 0'));
                catch
                end

                shouldUpdateThisID = isempty(useMonitorCaseIDs) || any(strcmp(monitorID, useMonitorCaseIDs));

                if ~shouldUpdateThisID
                    if isempty(currentLabel)
                        newLabelList{iMonitor} = monitorID;
                    else
                        newLabelList{iMonitor} = currentLabel;
                    end
                    continue;
                end

                matchIdx = find(strcmp(monitorID, ids), 1);
                if isempty(matchIdx)
                    if isempty(currentLabel)
                        warning('Monitor ID %s not found in mapping and Label 0 missing in %s', monitorID, fileName);
                        targetLabel = monitorID;
                    else
                        targetLabel = currentLabel;
                    end
                else
                    targetLabel = labels{matchIdx};
                end

                h5writeatt(fileName, cfgPath, 'Label 0', targetLabel);
                h5writeatt(fileName, cfgPath, 'Label 1', upper(targetLabel));

                newLabelList{iMonitor} = targetLabel;
            end

            h5writeatt(fileName, '/', 'MonitorLabelList', newLabelList);
            fprintf('Done processing file: %s\n', fileName);

        catch ME
            warning('Failed processing file: %s\nReason: %s', fileName, ME.message);
        end
    end
end

function token = getLastPathToken(pathText)
    parts = strsplit(pathText, '/');
    parts = parts(~cellfun(@isempty, parts));
    token = parts{end};
end

function label = normalizeLabel(raw)
    if isstring(raw)
        label = char(raw);
    elseif ischar(raw)
        label = raw;
    elseif isnumeric(raw)
        label = char(raw(:).');
    else
        label = char(string(raw));
    end

    nullIdx = find(label == char(0), 1, 'first');
    if ~isempty(nullIdx)
        label = label(1:nullIdx-1);
    end

    label = strtrim(label);
end