local NS = rawget(_G, "MCDVoiceCooldownNS") or {}
_G.MCDVoiceCooldownNS = NS

NS.Utils = NS.Utils or {}
local Utils = NS.Utils

function Utils.TrimText(value)
    return tostring(value or ""):match("^%s*(.-)%s*$")
end

function Utils.CanonicalPath(value)
    local path = Utils.TrimText(value)
    if path == "" then
        return ""
    end
    return (path:gsub("/", "\\"))
end

function Utils.StripAudioExtension(fileName)
    local value = tostring(fileName or "")
    return (value:gsub("%.[Oo][Gg][Gg]$", ""):gsub("%.[Mm][Pp]3$", ""))
end

function Utils.GetFileNameFromPath(value)
    local path = tostring(value or ""):gsub("/", "\\")
    return path:match("([^\\]+)$") or path
end

function Utils.NormalizeIconID(value)
    local iconID = tonumber(Utils.TrimText(value))
    if iconID and iconID > 0 then
        return math.floor(iconID)
    end
    return nil
end

function Utils.ClampNumber(value, minValue, maxValue, fallback)
    local number = tonumber(value)
    if not number then
        number = fallback or 0
    end
    if minValue and number < minValue then
        number = minValue
    end
    if maxValue and number > maxValue then
        number = maxValue
    end
    return number
end
