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

NS.ImportExportUtil = NS.ImportExportUtil or {}

local Util = NS.ImportExportUtil
local CONST = NS.Constants or {}
local Utils = NS.Utils or {}

local ALL_CLASSES_ID = CONST.ALL_CLASSES_ID or 0
local ALL_SPECS_ID = CONST.ALL_SPECS_ID or 0
local OBJECT_TYPE_SPELL = CONST.OBJECT_TYPE_SPELL or "spell"
local OBJECT_TYPE_ITEM = CONST.OBJECT_TYPE_ITEM or "item"

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

local function GetApi()
    return NS.API
end

function Util:DeepCopyTable(value, seen)
    if type(value) ~= "table" then
        return value
    end
    seen = seen or {}
    if seen[value] then
        return seen[value]
    end
    local copy = {}
    seen[value] = copy
    for k, v in pairs(value) do
        copy[self:DeepCopyTable(k, seen)] = self:DeepCopyTable(v, seen)
    end
    return copy
end

function Util:SanitizeEntryForImport(entry)
    if type(entry) ~= "table" then
        return nil
    end
    local spellId = tonumber(entry.spellId) or 0
    if spellId <= 0 then
        return nil
    end
    local modeTts, modeSound = "tts", "sound"
    local api = GetApi()
    if api and type(api.GetModes) == "function" then
        modeTts, modeSound = api.GetModes()
    end
    local notifyMode = tostring(entry.notifyMode or modeSound)
    if notifyMode ~= modeTts then
        notifyMode = modeSound
    end
    local soundFields
    if NS.AceOptions and type(NS.AceOptions.ResolveSoundSourceFields) == "function" then
        local sourceEntry = self:DeepCopyTable(entry)
        sourceEntry.notifyMode = notifyMode
        soundFields = NS.AceOptions:ResolveSoundSourceFields(sourceEntry, modeTts, modeSound)
    else
        local soundPath = tostring(entry.soundPath or ""):gsub("/", "\\")
        local soundSource = tostring(entry.soundSource or "")
        soundFields = {
            notifyMode = notifyMode,
            soundSource = (notifyMode == modeTts and "tts") or (soundSource ~= "" and soundSource or "custom"),
            soundPath = soundPath,
            sharedMediaSound = TrimText(entry.sharedMediaSound or entry.sharedMediaName or ""),
        }
    end
    notifyMode = soundFields.notifyMode
    local entryType = tostring(entry.entryType or "cooldown")
    if entryType ~= "cast" then
        entryType = "cooldown"
    end

    local objectType = tostring(entry.objectType or "")
    if api and type(api.ResolveObjectType) == "function" then
        objectType = api.ResolveObjectType(spellId, objectType)
    end
    if objectType ~= OBJECT_TYPE_ITEM then
        objectType = OBJECT_TYPE_SPELL
    end

    local sanitized = {
        entryType = entryType,
        objectType = objectType,
        spellName = TrimText(entry.spellName or ""),
        spellId = math.floor(spellId),
        itemID = (objectType == OBJECT_TYPE_ITEM) and math.floor(tonumber(entry.itemID or spellId) or spellId) or nil,
        triggerSpellID = math.floor(tonumber(entry.triggerSpellID or entry.triggerSpellId) or 0),
        triggerSpellName = TrimText(entry.triggerSpellName or ""),
        baseCD = tonumber(string.format("%.2f", tonumber(entry.baseCD) or 0)) or 0,
        fixedCD = true,
        checkTalent = entry.checkTalent == true and (tonumber(entry.talentId) or 0) > 0,
        talentId = math.floor(tonumber(entry.talentId) or 0),
        talentName = TrimText(entry.talentName or ""),
        talentCD = tonumber(string.format("%.2f", tonumber(entry.talentCD) or 0)) or 0,
        chargeInput = 1,
        notifyMode = notifyMode,
        ttsText = tostring(entry.ttsText or ""),
        ttsRate = math.max(-10, math.min(10, tonumber(entry.ttsRate) or 0)),
        delayEnabled = entryType == "cast" and entry.delayEnabled == true,
        delaySeconds = entryType == "cast" and math.max(0, tonumber(string.format("%.2f", tonumber(entry.delaySeconds) or 0)) or 0) or 0,
        soundPath = soundFields.soundPath or "",
        soundSource = soundFields.soundSource or nil,
        sharedMediaSound = (soundFields.soundSource == "sharedmedia" and TrimText(soundFields.sharedMediaSound or "") ~= "") and soundFields.sharedMediaSound or nil,
    }

    if objectType == OBJECT_TYPE_ITEM and (tonumber(sanitized.triggerSpellID) or 0) <= 0 then
        sanitized.triggerSpellID = 0
    end

    return sanitized
end

function Util:GetGlobalScopeIDs()
    return ALL_CLASSES_ID, ALL_SPECS_ID
end
