local _, ns = ...
local L = ns.L or {}

local FEATURE_ID = "stat_focus"

local STYLE_BLOCK = "block"
local STYLE_DOTS = "dots"
local STYLE_LINES = "lines"
local STYLE_FULL = "full"
local STYLE_COMPACT = "compact"

local MODE_PRESET = "preset"
local MODE_CUSTOM = "custom"

local DEFAULT_STAT_ORDER = { "HASTE", "MASTERY", "CRIT", "VERSATILITY" }
local DOT_TEXTURE_TOKEN = "stat_focus_dot_"
local DOT_TEXTURES = {
    [1] = "Interface\\AddOns\\Vaultloom\\Assets\\stat_focus_dot_orange",
    [2] = "Interface\\AddOns\\Vaultloom\\Assets\\stat_focus_dot_purple",
    [3] = "Interface\\AddOns\\Vaultloom\\Assets\\stat_focus_dot_blue",
    [4] = "Interface\\AddOns\\Vaultloom\\Assets\\stat_focus_dot_green",
}

local STAT_PRESETS = {
    DEATHKNIGHT = {
        [1] = { { "HASTE" }, { "MASTERY", "CRIT", "VERSATILITY" } },
        [2] = { { "CRIT" }, { "MASTERY" }, { "HASTE" }, { "VERSATILITY" } },
        [3] = { { "MASTERY" }, { "CRIT" }, { "HASTE" }, { "VERSATILITY" } },
    },
    DEMONHUNTER = {
        [1] = { { "CRIT" }, { "MASTERY" }, { "HASTE" }, { "VERSATILITY" } },
        [2] = { { "HASTE" }, { "CRIT" }, { "VERSATILITY" }, { "MASTERY" } },
    },
    DRUID = {
        [1] = { { "MASTERY" }, { "HASTE", "CRIT" }, { "VERSATILITY" } },
        [2] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
        [3] = { { "HASTE" }, { "VERSATILITY" }, { "CRIT" }, { "MASTERY" } },
        [4] = { { "HASTE" }, { "MASTERY" }, { "VERSATILITY" }, { "CRIT" } },
    },
    EVOKER = {
        [1] = { { "CRIT" }, { "HASTE" }, { "MASTERY" }, { "VERSATILITY" } },
        [2] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
        [3] = { { "CRIT" }, { "HASTE" }, { "MASTERY" }, { "VERSATILITY" } },
    },
    HUNTER = {
        [1] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
        [2] = { { "CRIT" }, { "MASTERY" }, { "VERSATILITY" }, { "HASTE" } },
        [3] = { { "MASTERY" }, { "CRIT", "HASTE" }, { "VERSATILITY" } },
    },
    MAGE = {
        [1] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
        [2] = { { "HASTE" }, { "MASTERY" }, { "VERSATILITY" }, { "CRIT" } },
        [3] = { { "MASTERY" }, { "CRIT" }, { "HASTE" }, { "VERSATILITY" } },
    },
    MONK = {
        [1] = { { "VERSATILITY", "CRIT", "MASTERY" }, { "HASTE" } },
        [2] = { { "HASTE" }, { "CRIT" }, { "VERSATILITY" }, { "MASTERY" } },
        [3] = { { "HASTE" }, { "CRIT" }, { "MASTERY" }, { "VERSATILITY" } },
    },
    PALADIN = {
        [1] = { { "MASTERY" }, { "HASTE", "CRIT" }, { "VERSATILITY" } },
        [2] = { { "HASTE" }, { "VERSATILITY" }, { "MASTERY" }, { "CRIT" } },
        [3] = { { "MASTERY" }, { "CRIT" }, { "HASTE" }, { "VERSATILITY" } },
    },
    PRIEST = {
        [1] = { { "HASTE" }, { "CRIT" }, { "MASTERY" }, { "VERSATILITY" } },
        [2] = { { "CRIT" }, { "VERSATILITY", "MASTERY" }, { "HASTE" } },
        [3] = { { "HASTE" }, { "MASTERY" }, { "CRIT" }, { "VERSATILITY" } },
    },
    ROGUE = {
        [1] = { { "CRIT" }, { "HASTE" }, { "MASTERY" }, { "VERSATILITY" } },
        [2] = { { "HASTE" }, { "CRIT" }, { "VERSATILITY" }, { "MASTERY" } },
        [3] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
    },
    SHAMAN = {
        [1] = { { "MASTERY" }, { "HASTE", "CRIT" }, { "VERSATILITY" } },
        [2] = { { "MASTERY" }, { "HASTE" }, { "CRIT" }, { "VERSATILITY" } },
        [3] = { { "CRIT" }, { "MASTERY", "VERSATILITY" }, { "HASTE" } },
    },
    WARLOCK = {
        [1] = { { "MASTERY", "CRIT" }, { "HASTE" }, { "VERSATILITY" } },
        [2] = { { "HASTE", "CRIT" }, { "MASTERY" }, { "VERSATILITY" } },
        [3] = { { "HASTE" }, { "MASTERY", "CRIT" }, { "VERSATILITY" } },
    },
    WARRIOR = {
        [1] = { { "CRIT" }, { "HASTE" }, { "MASTERY" }, { "VERSATILITY" } },
        [2] = { { "HASTE" }, { "MASTERY" }, { "CRIT" }, { "VERSATILITY" } },
        [3] = { { "HASTE" }, { "CRIT" }, { "VERSATILITY" }, { "MASTERY" } },
    },
}

local STAT_DEFINITIONS = {
    CRIT = {
        fallback = "Critical Strike",
        globals = { "ITEM_MOD_CRIT_RATING_SHORT", "STAT_CRITICAL_STRIKE", "ITEM_MOD_CRIT_RATING" },
    },
    HASTE = {
        fallback = "Haste",
        globals = { "ITEM_MOD_HASTE_RATING_SHORT", "STAT_HASTE", "ITEM_MOD_HASTE_RATING" },
    },
    MASTERY = {
        fallback = "Mastery",
        globals = { "ITEM_MOD_MASTERY_RATING_SHORT", "STAT_MASTERY", "ITEM_MOD_MASTERY_RATING" },
    },
    VERSATILITY = {
        fallback = "Versatility",
        globals = { "ITEM_MOD_VERSATILITY", "STAT_VERSATILITY", "ITEM_MOD_VERSATILITY_RATING" },
    },
}

local STAT_ALIASES = {
    crit = "CRIT",
    critical = "CRIT",
    ["critical strike"] = "CRIT",
    krit = "CRIT",
    kritisch = "CRIT",
    haste = "HASTE",
    tempo = "HASTE",
    mastery = "MASTERY",
    meisterschaft = "MASTERY",
    vers = "VERSATILITY",
    versa = "VERSATILITY",
    versatility = "VERSATILITY",
    vielseitigkeit = "VERSATILITY",
}

local RANK_COLORS = {
    [1] = { r = 1.00, g = 0.50, b = 0.00 },
    [2] = { r = 0.64, g = 0.21, b = 0.93 },
    [3] = { r = 0.00, g = 0.44, b = 0.87 },
    [4] = { r = 0.12, g = 1.00, b = 0.00 },
}

local StatFocusRuntime = {
    enabled = false,
    hooksReady = false,
    statLookup = nil,
}
ns.StatFocusRuntime = StatFocusRuntime

local function getFeatureDB(create)
    local db = ns.EnsureFeatureDB and ns:EnsureFeatureDB() or nil
    if type(db) ~= "table" then
        return nil
    end

    if create then
        db.statFocus = type(db.statFocus) == "table" and db.statFocus or {}
        return db.statFocus
    end

    return type(db.statFocus) == "table" and db.statFocus or nil
end

local function getCurrentCharacterKey()
    if ns.GetCurrentCharacterInfo then
        local ok, info = pcall(ns.GetCurrentCharacterInfo, ns)
        if ok and type(info) == "table" and type(info.key) == "string" and info.key ~= "" then
            return info.key
        end
    end

    local name = type(UnitName) == "function" and UnitName("player") or "Player"
    local realm = type(GetRealmName) == "function" and GetRealmName() or ""
    return tostring(name or "Player") .. "-" .. tostring(realm or "")
end

local function getCurrentSpecContext()
    local classToken = nil
    if type(UnitClass) == "function" then
        local _
        _, classToken = UnitClass("player")
    end

    local specIndex = type(GetSpecialization) == "function" and GetSpecialization() or nil
    classToken = type(classToken) == "string" and classToken or nil
    specIndex = tonumber(specIndex)
    if not classToken or not specIndex or specIndex < 1 then
        return nil, nil, nil
    end

    return classToken, specIndex, classToken .. ":" .. tostring(specIndex)
end

local function getSpecName()
    if type(GetSpecialization) ~= "function" or type(GetSpecializationInfo) ~= "function" then
        return nil
    end

    local specIndex = GetSpecialization()
    if not specIndex then
        return nil
    end

    local _, specName = GetSpecializationInfo(specIndex)
    return specName
end

local function copyFlatStatsToTiers(stats)
    if type(stats) ~= "table" then
        return nil
    end

    local tiers = {}
    for _, stat in ipairs(stats) do
        if STAT_DEFINITIONS[stat] then
            tiers[#tiers + 1] = { stat }
        end
    end
    return #tiers > 0 and tiers or nil
end

local function flattenTiers(tiers)
    local result = {}
    local seen = {}
    for _, tier in ipairs(tiers or {}) do
        for _, stat in ipairs(tier or {}) do
            if STAT_DEFINITIONS[stat] and not seen[stat] then
                result[#result + 1] = stat
                seen[stat] = true
            end
        end
    end
    return result
end

local function buildRankMap(tiers)
    local rankMap = {}
    local ordered = {}
    for rank, tier in ipairs(tiers or {}) do
        local color = RANK_COLORS[rank] or RANK_COLORS[#RANK_COLORS]
        for _, stat in ipairs(tier or {}) do
            if STAT_DEFINITIONS[stat] and not rankMap[stat] then
                rankMap[stat] = {
                    rank = rank,
                    color = color,
                }
                ordered[#ordered + 1] = {
                    stat = stat,
                    rank = rank,
                    color = color,
                }
            end
        end
    end
    return rankMap, ordered
end

local function clampColorChannel(value)
    value = tonumber(value) or 0
    if value < 0 then
        value = 0
    elseif value > 1 then
        value = 1
    end
    return math.floor(value * 255 + 0.5)
end

local function colorToHex(color)
    color = color or RANK_COLORS[4]
    return string.format("|cff%02x%02x%02x", clampColorChannel(color.r), clampColorChannel(color.g), clampColorChannel(color.b))
end

local function colorText(text, color)
    return colorToHex(color) .. tostring(text or "") .. "|r"
end

local function getDotTexture(rankInfo)
    local texture = DOT_TEXTURES[rankInfo and rankInfo.rank or 4] or DOT_TEXTURES[4]
    return string.format("|T%s:9:9:0:0|t", texture)
end

local function getStatLabel(stat)
    local definition = STAT_DEFINITIONS[stat]
    if not definition then
        return tostring(stat or "")
    end

    for _, globalName in ipairs(definition.globals or {}) do
        local value = _G[globalName]
        if type(value) == "string" and value ~= "" then
            return value
        end
    end

    return definition.fallback
end

local function buildStatLookup()
    local lookup = {}
    for stat, definition in pairs(STAT_DEFINITIONS) do
        for _, globalName in ipairs(definition.globals or {}) do
            local value = _G[globalName]
            if type(value) == "string" and value ~= "" then
                lookup[value] = stat
            end
        end
        lookup[definition.fallback] = stat
    end
    return lookup
end

local function findStatInText(text, lookup)
    if type(text) ~= "string" or text == "" then
        return nil
    end

    for localizedStat, stat in pairs(lookup or {}) do
        if type(localizedStat) == "string" and localizedStat ~= "" then
            local ok, found = pcall(string.find, text, localizedStat, 1, true)
            if ok and found then
                return stat
            end
        end
    end

    return nil
end

local function formatTierSummary(ordered, separator)
    local parts = {}
    for _, entry in ipairs(ordered or {}) do
        parts[#parts + 1] = colorText(getStatLabel(entry.stat), entry.color)
    end
    return table.concat(parts, separator or "  ")
end

local function normalizeCustomOrder(stats, fallbackTiers)
    local order = {}
    local seen = {}
    for _, stat in ipairs(stats or {}) do
        if STAT_DEFINITIONS[stat] and not seen[stat] then
            order[#order + 1] = stat
            seen[stat] = true
        end
    end

    local fallbackOrder = flattenTiers(fallbackTiers)
    if #fallbackOrder == 0 then
        fallbackOrder = DEFAULT_STAT_ORDER
    end

    for _, stat in ipairs(fallbackOrder) do
        if STAT_DEFINITIONS[stat] and not seen[stat] then
            order[#order + 1] = stat
            seen[stat] = true
        end
    end

    for _, stat in ipairs(DEFAULT_STAT_ORDER) do
        if STAT_DEFINITIONS[stat] and not seen[stat] then
            order[#order + 1] = stat
            seen[stat] = true
        end
    end

    return #order > 0 and order or nil
end

local function parseStatToken(raw)
    raw = tostring(raw or ""):lower()
    raw = raw:gsub("[,;>]+", " ")
    raw = raw:gsub("^%s+", ""):gsub("%s+$", "")
    return STAT_ALIASES[raw]
end

local function splitWords(message)
    local words = {}
    for word in tostring(message or ""):gmatch("%S+") do
        words[#words + 1] = word
    end
    return words
end

local function getModeBucket(create)
    local db = getFeatureDB(create)
    if type(db) ~= "table" then
        return nil
    end

    if create then
        db.mode = type(db.mode) == "table" and db.mode or {}
        return db.mode
    end

    return type(db.mode) == "table" and db.mode or nil
end

local function getCustomBucket(create)
    local db = getFeatureDB(create)
    if type(db) ~= "table" then
        return nil
    end

    if create then
        db.custom = type(db.custom) == "table" and db.custom or {}
        return db.custom
    end

    return type(db.custom) == "table" and db.custom or nil
end

function StatFocusRuntime:GetPresetTiers()
    local classToken, specIndex = getCurrentSpecContext()
    if not classToken or not specIndex then
        return nil
    end

    local classPresets = STAT_PRESETS[classToken]
    return type(classPresets) == "table" and classPresets[specIndex] or nil
end

function StatFocusRuntime:GetCurrentMode()
    local _, _, specKey = getCurrentSpecContext()
    if not specKey then
        return MODE_PRESET
    end

    local modes = getModeBucket(false)
    local characterKey = getCurrentCharacterKey()
    local characterModes = type(modes) == "table" and type(modes[characterKey]) == "table" and modes[characterKey] or nil
    local mode = characterModes and characterModes[specKey] or nil
    return mode == MODE_CUSTOM and MODE_CUSTOM or MODE_PRESET
end

function StatFocusRuntime:SetCurrentMode(mode)
    mode = mode == MODE_CUSTOM and MODE_CUSTOM or MODE_PRESET
    local _, _, specKey = getCurrentSpecContext()
    if not specKey then
        return mode
    end

    local modes = getModeBucket(true)
    if type(modes) ~= "table" then
        return mode
    end

    local characterKey = getCurrentCharacterKey()
    modes[characterKey] = type(modes[characterKey]) == "table" and modes[characterKey] or {}
    modes[characterKey][specKey] = mode

    if mode == MODE_CUSTOM and not self:GetCustomTiers() then
        local order = normalizeCustomOrder(nil, self:GetPresetTiers())
        local custom = getCustomBucket(true)
        if type(custom) == "table" and order then
            custom[characterKey] = type(custom[characterKey]) == "table" and custom[characterKey] or {}
            custom[characterKey][specKey] = order
        end
    end

    return mode
end

function StatFocusRuntime:GetCustomTiers()
    local _, _, specKey = getCurrentSpecContext()
    if not specKey then
        return nil
    end

    local custom = getCustomBucket(false)
    local characterKey = getCurrentCharacterKey()
    local characterCustom = type(custom) == "table" and type(custom[characterKey]) == "table" and custom[characterKey] or nil
    local order = characterCustom and characterCustom[specKey] or nil
    return copyFlatStatsToTiers(order)
end

function StatFocusRuntime:SetCustomOrder(stats)
    local classToken, specIndex, specKey = getCurrentSpecContext()
    if not classToken or not specIndex or not specKey then
        return nil
    end

    local order = normalizeCustomOrder(stats, self:GetPresetTiers())
    if not order then
        return nil
    end

    local custom = getCustomBucket(true)
    if type(custom) ~= "table" then
        return nil
    end

    local characterKey = getCurrentCharacterKey()
    custom[characterKey] = type(custom[characterKey]) == "table" and custom[characterKey] or {}
    custom[characterKey][specKey] = order
    self:SetCurrentMode(MODE_CUSTOM)
    return order
end

function StatFocusRuntime:ClearCustomOrder()
    local _, _, specKey = getCurrentSpecContext()
    if not specKey then
        return
    end

    local custom = getCustomBucket(false)
    local characterKey = getCurrentCharacterKey()
    if type(custom) == "table" and type(custom[characterKey]) == "table" then
        custom[characterKey][specKey] = nil
    end
    self:SetCurrentMode(MODE_PRESET)
end

function StatFocusRuntime:GetActiveTiers()
    local preset = self:GetPresetTiers()
    local mode = self:GetCurrentMode()
    if mode == MODE_CUSTOM then
        local custom = self:GetCustomTiers()
        if custom then
            return custom, MODE_CUSTOM
        end
    end
    return preset, MODE_PRESET
end

function StatFocusRuntime:GetSummaryText()
    local tiers, mode = self:GetActiveTiers()
    if not tiers then
        return L.FEATURE_STAT_FOCUS_NO_SPEC or "No preset for the current specialization."
    end

    local _, ordered = buildRankMap(tiers)
    local modeText = mode == MODE_CUSTOM and (L.FEATURE_STAT_FOCUS_MODE_CUSTOM or "Custom") or (L.FEATURE_STAT_FOCUS_MODE_PRESET or "Preset")
    local specName = getSpecName()
    local label = specName and (modeText .. " - " .. specName) or modeText
    return label .. ": " .. formatTierSummary(ordered, " > ")
end

local function ensureTooltipResetHook(tooltip)
    if not tooltip or tooltip.VaultloomStatFocusClearHook then
        return
    end

    if tooltip.HookScript then
        tooltip:HookScript("OnTooltipCleared", function(self)
            self.VaultloomStatFocusAdded = false
        end)
        tooltip.VaultloomStatFocusClearHook = true
    end
end

function StatFocusRuntime:ApplyLineHints(tooltip, rankMap, colorLines, addDots)
    local lookup = self.statLookup or buildStatLookup()
    self.statLookup = lookup

    local lineCount = tooltip and tooltip.NumLines and tooltip:NumLines() or 0
    for index = 2, lineCount do
        local line = _G[(tooltip:GetName() or "") .. "TextLeft" .. tostring(index)]
        if line and line.GetText then
            local text = line:GetText()
            local okText = type(text) == "string" and pcall(string.len, text)
            if okText then
                local stat = findStatInText(text, lookup)
                local rankInfo = stat and rankMap[stat] or nil
                if rankInfo and rankInfo.color then
                    if colorLines and line.SetTextColor then
                        line:SetTextColor(rankInfo.color.r, rankInfo.color.g, rankInfo.color.b, 1)
                    end
                    if addDots and line.SetText and not text:find(DOT_TEXTURE_TOKEN, 1, true) then
                        line:SetText(text .. "  " .. getDotTexture(rankInfo))
                    end
                end
            end
        end
    end
end

function StatFocusRuntime:AddSummary(tooltip, ordered, style)
    if not tooltip or tooltip.VaultloomStatFocusAdded then
        return
    end

    ensureTooltipResetHook(tooltip)
    tooltip.VaultloomStatFocusAdded = true

    local header = L.FEATURE_STAT_FOCUS_TOOLTIP_HEADER or "Stat Focus"
    if style == STYLE_COMPACT then
        tooltip:AddLine(colorText(header .. ": ", RANK_COLORS[1]) .. formatTierSummary(ordered, " > "), 1, 1, 1, true)
    else
        tooltip:AddLine(" ")
        tooltip:AddLine(header, 1, 0.82, 0.24, true)
        tooltip:AddLine(formatTierSummary(ordered, "  "), 1, 1, 1, true)
    end
end

function StatFocusRuntime:ApplyTooltip(tooltip)
    if self.enabled ~= true or not tooltip then
        return
    end

    local tiers = self:GetActiveTiers()
    if not tiers then
        return
    end

    local rankMap, ordered = buildRankMap(tiers)
    if not ordered or #ordered == 0 then
        return
    end

    local style = ns.GetFeatureOptionValue and ns:GetFeatureOptionValue(FEATURE_ID, "tooltip_style") or STYLE_BLOCK
    if style == STYLE_LINES or style == STYLE_FULL then
        self:ApplyLineHints(tooltip, rankMap, true, false)
    elseif style == STYLE_DOTS then
        self:ApplyLineHints(tooltip, rankMap, false, true)
    end
    if style == STYLE_BLOCK or style == STYLE_FULL or style == STYLE_COMPACT then
        self:AddSummary(tooltip, ordered, style)
    end

    if tooltip.Show then
        tooltip:Show()
    end
end

function StatFocusRuntime:EnsureHooks()
    if self.hooksReady then
        return
    end

    self.hooksReady = true

    if TooltipDataProcessor and TooltipDataProcessor.AddTooltipPostCall and Enum and Enum.TooltipDataType then
        TooltipDataProcessor.AddTooltipPostCall(Enum.TooltipDataType.Item, function(tooltip)
            StatFocusRuntime:ApplyTooltip(tooltip)
        end)
        return
    end

    if GameTooltip and GameTooltip.HookScript then
        GameTooltip:HookScript("OnTooltipSetItem", function(tooltip)
            StatFocusRuntime:ApplyTooltip(tooltip)
        end)
    end
end

function StatFocusRuntime:SetEnabled(enabled)
    self.enabled = enabled == true
    self:EnsureHooks()
end

function ns:HandleStatFocusSlash(message)
    local words = splitWords(message)
    local first = words[1] and words[1]:lower() or ""

    if first == "" or first == "show" or first == "status" then
        self:Print(StatFocusRuntime:GetSummaryText())
        self:Print(L.FEATURE_STAT_FOCUS_SLASH_HELP or "Set custom order: /vl stats haste mastery crit vers. Use /vl stats preset to return to presets.")
        return true
    end

    if first == "preset" or first == "auto" then
        StatFocusRuntime:SetCurrentMode(MODE_PRESET)
        self:Print(L.FEATURE_STAT_FOCUS_PRESET_ENABLED or "Stat Focus uses the automatic preset for this character and specialization.")
        self:Print(StatFocusRuntime:GetSummaryText())
        return true
    end

    if first == "reset" or first == "clear" then
        StatFocusRuntime:ClearCustomOrder()
        self:Print(L.FEATURE_STAT_FOCUS_CUSTOM_CLEARED or "Custom Stat Focus order cleared for this character and specialization.")
        self:Print(StatFocusRuntime:GetSummaryText())
        return true
    end

    local parsed = {}
    local startIndex = (first == "custom" or first == "eigen") and 2 or 1
    for index = startIndex, #words do
        local stat = parseStatToken(words[index])
        if stat then
            parsed[#parsed + 1] = stat
        end
    end

    if #parsed == 0 and (first == "custom" or first == "eigen") then
        StatFocusRuntime:SetCurrentMode(MODE_CUSTOM)
        self:Print(L.FEATURE_STAT_FOCUS_CUSTOM_ENABLED or "Stat Focus uses your custom order for this character and specialization.")
        self:Print(StatFocusRuntime:GetSummaryText())
        return true
    end

    if #parsed > 0 then
        local order = StatFocusRuntime:SetCustomOrder(parsed)
        if order then
            self:Print(L.FEATURE_STAT_FOCUS_CUSTOM_SAVED or "Custom Stat Focus order saved for this character and specialization.")
            self:Print(StatFocusRuntime:GetSummaryText())
        else
            self:Print(L.FEATURE_STAT_FOCUS_CUSTOM_FAILED or "Could not save a custom Stat Focus order for the current specialization.")
        end
        return true
    end

    self:Print(L.FEATURE_STAT_FOCUS_SLASH_HELP or "Set custom order: /vl stats haste mastery crit vers. Use /vl stats preset to return to presets.")
    return true
end

ns:RegisterFeatureDefinition(FEATURE_ID, {
    id = FEATURE_ID,
    order = 30,
    category = "character",
    title = function() return L.FEATURE_STAT_FOCUS_TITLE or "Stat Focus" end,
    description = function() return L.FEATURE_STAT_FOCUS_DESCRIPTION or "Shows your current class and specialization stat priority in item tooltips.\nColors: orange = best/equal best, purple = second, blue = third, green = fourth." end,
    note = function() return L.FEATURE_STAT_FOCUS_NOTE or "Automatic presets follow your current class and specialization." end,
    previewLabel = function() return L.FEATURE_STAT_FOCUS_PREVIEW_LABEL or "Gear Tooltip" end,
    previewNote = function() return L.FEATURE_STAT_FOCUS_PREVIEW_NOTE or "Tooltip styles: compact line, summary block, colored stat lines, or both." end,
    optionToggle = {
        key = "tooltip_style",
        label = function() return L.FEATURE_STAT_FOCUS_STYLE_LABEL or "Style" end,
        values = { STYLE_BLOCK, STYLE_DOTS, STYLE_LINES, STYLE_FULL, STYLE_COMPACT },
        defaultValue = STYLE_BLOCK,
        valueLabels = {
            block = function() return L.FEATURE_STAT_FOCUS_STYLE_BLOCK or "Block" end,
            dots = function() return L.FEATURE_STAT_FOCUS_STYLE_DOTS or "Dots" end,
            lines = function() return L.FEATURE_STAT_FOCUS_STYLE_LINES or "Lines" end,
            full = function() return L.FEATURE_STAT_FOCUS_STYLE_FULL or "Both" end,
            compact = function() return L.FEATURE_STAT_FOCUS_STYLE_COMPACT or "Compact" end,
        },
    },
    requiresReload = false,
    apply = function(isEnabled)
        StatFocusRuntime:SetEnabled(isEnabled == true)
    end,
    onOptionChanged = function(value, optionKey)
        if optionKey == "priority_mode" then
            StatFocusRuntime:SetCurrentMode(value)
        end
    end,
})
