function changeH5LabelsV2(folderName, oldLabels, newLabels, updateSensorLabel0, updateSensorLabel1)
%CHANGEH5LABELS Rename sensor labels in .h5 files and refresh root label list.
%
%   Default behavior:
%   - Replace Shank -> Leg in Label 0 (case-insensitive, whole-word)
%   - Write Label 1 as upper(Label 0), so SHANK -> LEG
%
%   Example:
%   changeH5Labels('/path/to/h5/files', {'Shank'}, {'Leg'}, true, true);

    if nargin < 1 || isempty(folderName)
        folderName = '/Users/mahmoud/Downloads';
    end
    if nargin < 2 || isempty(oldLabels)
        oldLabels = {'Shank'};
    end
    if nargin < 3 || isempty(newLabels)
        newLabels = {'Leg'};
    end
    if nargin < 4 || isempty(updateSensorLabel0)
        updateSensorLabel0 = true;
    end
    if nargin < 5 || isempty(updateSensorLabel1)
        updateSensorLabel1 = true;
    end

    if numel(oldLabels) ~= numel(newLabels)
        error('oldLabels and newLabels 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

    fprintf('Found %d file(s) in %s\n', numel(fileNames), folderName);

    nFilesProcessed = 0;
    nFilesFailed = 0;

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

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

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

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

            for i = 1:numel(groups)
                cfgPath = [groups(i).Name '/Configuration'];

                currentLabelRaw = h5readatt(fileName, cfgPath, 'Label 0');
                currentLabel = normalizeLabel(currentLabelRaw);

                mappedLabel = currentLabel;

                % Apply user-defined replacements (whole-word, case-insensitive)
                for k = 1:numel(oldLabels)
                    pattern = ['\<' regexptranslate('escape', oldLabels{k}) '\>'];
                    mappedLabel = regexprep(mappedLabel, pattern, newLabels{k}, 'ignorecase');
                end

                % Ensure Shank -> Leg replacement is applied
                mappedLabel = regexprep(mappedLabel, '\<Shank\>', 'Leg', 'ignorecase');

                if updateSensorLabel0
                    h5writeatt(fileName, cfgPath, 'Label 0', mappedLabel);
                end

                if updateSensorLabel1
                    h5writeatt(fileName, cfgPath, 'Label 1', upper(mappedLabel));
                end

                newLabelList{i} = mappedLabel;
            end

            h5writeatt(fileName, '/', 'MonitorLabelList', newLabelList);

            fprintf('Done: %s\n', fileName);
            nFilesProcessed = nFilesProcessed + 1;

        catch ME
            nFilesFailed = nFilesFailed + 1;
            warning('Failed: %s\n  Reason: %s', fileName, ME.message);
        end
    end

    fprintf('\nSummary: processed=%d, failed=%d\n', nFilesProcessed, nFilesFailed);
end

function label = normalizeLabel(raw)
%NORMALIZELABEL Convert HDF5 attribute payload to clean char row vector.

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

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

    label = strtrim(label);
end