TargetMarkerAssistant = TargetMarkerAssistant or {}
local TMA = TargetMarkerAssistant
local L = TargetMarkerAssistantL or {}

TMA.RESTRICTED_INTERRUPT_DANMAKU_SCROLL_START_RATIOS = { 1.0, 0.95, 0.90, 0.85, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50 }

function TMA.NormalizeRestrictedInterruptDanmakuScrollStartRatio(value)
    local number = tonumber(value) or 1.0
    if number > 1 then
        number = number / 100
    end

    local ratios = TMA.RESTRICTED_INTERRUPT_DANMAKU_SCROLL_START_RATIOS
    local closest = ratios[1]
    local closestDelta = math.abs(number - closest)
    for i = 2, #ratios do
        local delta = math.abs(number - ratios[i])
        if delta < closestDelta then
            closest = ratios[i]
            closestDelta = delta
        end
    end

    return closest
end

function TMA.GetClientDefaultFont()
    if GameFontNormal and GameFontNormal.GetFont then
        local font = select(1, GameFontNormal:GetFont())
        if font and font ~= "" then
            return font
        end
    end

    return STANDARD_TEXT_FONT or UNIT_NAME_FONT or DAMAGE_TEXT_FONT
end

function TMA.SetClientDefaultFont(fontObject, size, flags)
    if not fontObject or not fontObject.SetFont then
        return false
    end

    local font = TMA.GetClientDefaultFont and TMA.GetClientDefaultFont()
    if not font or font == "" then
        return false
    end

    local ok = pcall(fontObject.SetFont, fontObject, font, size or 12, flags or "")
    return ok == true
end

TMA.DEFAULT_RESTRICTED_INTERRUPT_DANMAKU = {
    enabled = true,
    prefix = "",
    color = { r = 1, g = 0.82, b = 0 },
    speed = 300,
    lifetime = 8,
    fadeInDuration = 0.25,
    fadeOutDuration = 0.35,
    fontSize = 22,
    fontOutline = "OUTLINE",
    fontShadow = true,
    shadowOffsetX = 1,
    shadowOffsetY = -1,
    maxDanmaku = 5,
    anchorPoint = "TOPLEFT",
    xOffset = 0,
    yOffset = -120,
    scrollHeight = 220,
    scrollStartRatio = 1.0,
    soundEnabled = false,
    sound = "ping",
    frameStrata = "MEDIUM",
    frameLevel = 10,
}

TMA.DEFAULT_SETTINGS = {
    allowClearFocus = false,
    modifier = "shift",
    mouseButton = "1",
    selectedMarker = 0,
    enableMarking = false,
    enableAnnounce = false,
    enableInterruptAnnounce = false,
    interruptAnnounceTemplate = L["INTERRUPT_CHAT_TEMPLATE_DEFAULT"],
    interruptAddonSyncEnabled = true,
    showClassColorInLocalNotice = true,
    interruptSpellMode = "auto",
    interruptSpellInput = "",
    interruptSpellID = nil,
    interruptSpellName = nil,
    interruptFocusMacroCreated = false,
    interruptSpellCooldowns = {},
    enableInterruptCooldownReadyAlert = true,
    debugInterruptAnnounce = false,
    enableCastAlert = false,
    castAlertSound = "cold_mature_male",
    castAlertChannel = "Master",
    announceMessage = L["ANNOUNCE_DEFAULT_MESSAGE"],
    announceChannel = "SAY",
    customInterruptSpellIDs = {},
    minimapButtonAngle = 225,
}

TMA.SETTINGS_PAGE_DEFAULT_KEYS = {
    "allowClearFocus",
    "modifier",
    "mouseButton",
    "selectedMarker",
    "enableMarking",
    "enableAnnounce",
    "announceMessage",
    "announceChannel",
}

TMA.INTERRUPT_ALERT_PAGE_DEFAULT_KEYS = {
    "enableCastAlert",
    "castAlertSound",
    "castAlertChannel",
}

TMA.INTERRUPT_ANNOUNCE_PAGE_DEFAULT_KEYS = {
    "enableInterruptAnnounce",
    "interruptAnnounceTemplate",
    "interruptAddonSyncEnabled",
    "showClassColorInLocalNotice",
    "interruptSpellMode",
    "interruptSpellInput",
    "interruptSpellID",
    "interruptSpellName",
    "interruptFocusMacroCreated",
    "interruptSpellCooldowns",
    "enableInterruptCooldownReadyAlert",
    "debugInterruptAnnounce",
    "restrictedInterruptDanmaku",
}

local legacyAnnounceMessages = {
    ["已标记 %s"] = true,
    ["Marked %s"] = true,
    ["我已标记 %s"] = true,
    ["我已標記 %s"] = true,
    ["我负责打断 %s"] = true,
    ["I interrupt %s"] = true,
    ["我負責打斷 %s"] = true,
}

local legacyInterruptTemplates = {
    ["{player} 已经打断 [{spell}]，下次打断还有 {cooldown} 秒。"] = true,
    ["{player} 已經打斷 [{spell}]，下次打斷還有 {cooldown} 秒。"] = true,
    ["{player} interrupted [{spell}]. Next interrupt in {cooldown} sec."] = true,
    ["{player} 尝试打断 [{spell}]，下次打断还有 {cooldown} 秒。"] = true,
    ["{player} 嘗試打斷 [{spell}]，下次打斷還有 {cooldown} 秒。"] = true,
    ["{player} attempted to interrupt [{spell}]. Next interrupt in {cooldown} sec."] = true,
    ["{player} 已对 [{target}] 施放 [{interrupt}]，下次打断还有 {cooldown} 秒。"] = true,
    ["{player} 已對 [{target}] 施放 [{interrupt}]，下次打斷還有 {cooldown} 秒。"] = true,
    ["{player} used [{interrupt}] on [{target}]. Next interrupt in {cooldown} sec."] = true,
}

function TMA.CopyDefaultValue(value)
    if type(value) ~= "table" then
        return value
    end

    local copy = {}
    for k, v in pairs(value) do
        copy[k] = TMA.CopyDefaultValue(v)
    end
    return copy
end

function TMA.EnsureRestrictedInterruptDanmakuDefaults()
    if not TargetMarkerAssistantDB then TargetMarkerAssistantDB = {} end

    if type(TargetMarkerAssistantDB.restrictedInterruptDanmaku) ~= "table" then
        TargetMarkerAssistantDB.restrictedInterruptDanmaku = {}
    end

    local cfg = TargetMarkerAssistantDB.restrictedInterruptDanmaku
    for key, value in pairs(TMA.DEFAULT_RESTRICTED_INTERRUPT_DANMAKU) do
        if cfg[key] == nil then
            cfg[key] = TMA.CopyDefaultValue(value)
        end
    end

    if type(cfg.color) ~= "table" then
        cfg.color = TMA.CopyDefaultValue(TMA.DEFAULT_RESTRICTED_INTERRUPT_DANMAKU.color)
    else
        for key, value in pairs(TMA.DEFAULT_RESTRICTED_INTERRUPT_DANMAKU.color) do
            if cfg.color[key] == nil then
                cfg.color[key] = value
            end
        end
    end

    if cfg.prefix == "[打断]" then
        cfg.prefix = ""
    end

    cfg.scrollStartRatio = TMA.NormalizeRestrictedInterruptDanmakuScrollStartRatio(cfg.scrollStartRatio)
end

function TMA.EnsureInterruptAnnounceDefaults()
    if not TargetMarkerAssistantDB then TargetMarkerAssistantDB = {} end

    if TargetMarkerAssistantDB.enableInterruptAnnounce == nil then
        TargetMarkerAssistantDB.enableInterruptAnnounce = false
    end
    if TargetMarkerAssistantDB.interruptAnnounceTemplate == nil
        or TargetMarkerAssistantDB.interruptAnnounceTemplate == ""
        or legacyInterruptTemplates[TargetMarkerAssistantDB.interruptAnnounceTemplate]
    then
        TargetMarkerAssistantDB.interruptAnnounceTemplate = L["INTERRUPT_CHAT_TEMPLATE_DEFAULT"]
    end
    if TargetMarkerAssistantDB.showClassColorInLocalNotice == nil then
        TargetMarkerAssistantDB.showClassColorInLocalNotice = true
    end
    if TargetMarkerAssistantDB.interruptAddonSyncEnabled == nil then
        TargetMarkerAssistantDB.interruptAddonSyncEnabled = true
    end
    if TargetMarkerAssistantDB.debugInterruptAnnounce == nil then
        TargetMarkerAssistantDB.debugInterruptAnnounce = false
    end
    if type(TargetMarkerAssistantDB.interruptSpellCooldowns) ~= "table" then
        TargetMarkerAssistantDB.interruptSpellCooldowns = {}
    end
    if TargetMarkerAssistantDB.enableInterruptCooldownReadyAlert == nil then
        TargetMarkerAssistantDB.enableInterruptCooldownReadyAlert = true
    end
    if TargetMarkerAssistantDB.interruptSpellMode ~= "auto"
        and TargetMarkerAssistantDB.interruptSpellMode ~= "manual"
    then
        TargetMarkerAssistantDB.interruptSpellMode = "auto"
    end

    TargetMarkerAssistantDB.interruptAnnounceEnabled = TargetMarkerAssistantDB.enableInterruptAnnounce
end

function TMA.EnsureDBAliases()
    TMA.EnsureInterruptAnnounceDefaults()
    TMA.EnsureRestrictedInterruptDanmakuDefaults()
    TMA.DB = TargetMarkerAssistantDB
end

function TMA.InitializeDB()
    if not TargetMarkerAssistantDB then TargetMarkerAssistantDB = {} end
    for k, v in pairs(TMA.DEFAULT_SETTINGS) do
        if TargetMarkerAssistantDB[k] == nil then
            TargetMarkerAssistantDB[k] = TMA.CopyDefaultValue(v)
        end
    end

    if legacyAnnounceMessages[TargetMarkerAssistantDB.announceMessage] then
        TargetMarkerAssistantDB.announceMessage = L["ANNOUNCE_DEFAULT_MESSAGE"]
    end

    if type(TargetMarkerAssistantDB.customInterruptSpellIDs) ~= "table" then
        TargetMarkerAssistantDB.customInterruptSpellIDs = {}
    end
    if type(TargetMarkerAssistantDB.interruptSpellCooldowns) ~= "table" then
        TargetMarkerAssistantDB.interruptSpellCooldowns = {}
    end

    if TargetMarkerAssistantDB.interruptAnnounceEnabled ~= nil then
        TargetMarkerAssistantDB.enableInterruptAnnounce = TargetMarkerAssistantDB.interruptAnnounceEnabled
    end

    if (TargetMarkerAssistantDB.interruptSpellInput == nil or TargetMarkerAssistantDB.interruptSpellInput == "")
        and type(TargetMarkerAssistantDB.interruptSpellName) == "string"
        and TargetMarkerAssistantDB.interruptSpellName ~= ""
    then
        TargetMarkerAssistantDB.interruptSpellInput = TargetMarkerAssistantDB.interruptSpellName
        TargetMarkerAssistantDB.interruptSpellID = nil
    end

    TargetMarkerAssistantDB.interruptAnnounceEnabled = TargetMarkerAssistantDB.enableInterruptAnnounce
    TMA.EnsureDBAliases()
end

function TMA.ResetKeysToDefaults(keys)
    if not TargetMarkerAssistantDB then TargetMarkerAssistantDB = {} end
    for _, key in ipairs(keys) do
        if key == "restrictedInterruptDanmaku" then
            TargetMarkerAssistantDB[key] = nil
        else
            TargetMarkerAssistantDB[key] = TMA.CopyDefaultValue(TMA.DEFAULT_SETTINGS[key])
        end
    end
    TMA.EnsureDBAliases()
end
