local addonName, WN = ...

WN = WN or {}
WN.name = addonName
WN.displayName = "WoWNext"
WN.version = "1.2.4"
WN.interfaceVersion = 120100
WN.seasonName = "Midnight • Curse of Ula-Tek"
WN.seasonShortName = "Curse of Ula-Tek"
WN.sections = {}
WN.sectionOrder = { "overview", "planner", "character", "gear", "activities", "endgame", "alts", "collections", "tools", "settings" }
WN.L = {}
WN.locales = {}

WN.colors = {
    bg = { 0.030, 0.042, 0.052, 0.965 },
    bgDeep = { 0.018, 0.027, 0.035, 0.985 },
    panel = { 0.047, 0.063, 0.075, 0.955 },
    panel2 = { 0.056, 0.075, 0.089, 0.970 },
    panelHover = { 0.075, 0.103, 0.118, 0.985 },
    border = { 0.105, 0.175, 0.205, 1 },
    borderSoft = { 0.070, 0.120, 0.142, 1 },
    accent = { 0.060, 0.835, 0.825, 1 },
    accentDim = { 0.035, 0.350, 0.385, 1 },
    accentBlue = { 0.10, 0.58, 0.92, 1 },
    green = { 0.24, 0.88, 0.48, 1 },
    yellow = { 1.00, 0.70, 0.18, 1 },
    orange = { 1.00, 0.43, 0.12, 1 },
    red = { 0.95, 0.28, 0.30, 1 },
    purple = { 0.70, 0.34, 1.00, 1 },
    text = { 0.92, 0.96, 0.97, 1 },
    muted = { 0.58, 0.67, 0.71, 1 },
    faint = { 0.36, 0.44, 0.48, 1 },
    black = { 0, 0, 0, 1 },
}

WN.icons = {
    overview = "Interface\\Icons\\INV_Misc_House_05",
    planner = "Interface\\Icons\\INV_Misc_Note_06",
    endgame = "Interface\\Icons\\Achievement_ChallengeMode_Gold",
    alts = "Interface\\Icons\\Achievement_GuildPerk_EverybodysFriend",
    character = "Interface\\Icons\\Achievement_Character_Human_Female",
    gear = "Interface\\Icons\\INV_Shield_06",
    activities = "Interface\\Icons\\INV_Sword_04",
    collections = "Interface\\Icons\\INV_Misc_Book_09",
    tools = "Interface\\Icons\\Trade_Engineering",
    settings = "Interface\\Icons\\INV_Gizmo_02",
    mythic = "Interface\\Icons\\Achievement_ChallengeMode_Gold",
    raid = "Interface\\Icons\\Achievement_Boss_Kiljaedan",
    delves = "Interface\\Icons\\INV_Misc_Map_01",
    pvp = "Interface\\Icons\\Achievement_PVP_A_A",
    reputation = "Interface\\Icons\\Achievement_Reputation_08",
    profession = "Interface\\Icons\\Trade_Alchemy",
    mount = "Interface\\Icons\\Ability_Mount_RidingHorse",
    pet = "Interface\\Icons\\INV_Box_PetCarrier_01",
    toy = "Interface\\Icons\\INV_Misc_Toy_10",
    transmog = "Interface\\Icons\\INV_Chest_Cloth_17",
    achievement = "Interface\\Icons\\Achievement_General",
    group = "Interface\\Icons\\Achievement_GuildPerk_EverybodysFriend",
    calendar = "Interface\\Icons\\INV_Misc_Note_01",
    auction = "Interface\\Icons\\INV_Misc_Coin_02",
    map = "Interface\\Icons\\INV_Misc_Map02",
    locations = "Interface\\Icons\\INV_Misc_Map_01",
    talents = "Interface\\Icons\\Ability_Marksmanship",
    vault = "Interface\\Icons\\INV_Chest_Cloth_17",
    info = "Interface\\Icons\\INV_Misc_QuestionMark",
    warning = "Interface\\DialogFrame\\UI-Dialog-Icon-AlertNew",
    check = "Interface\\RaidFrame\\ReadyCheck-Ready",
}

local function IsSecret(value)
    if type(issecretvalue) ~= "function" then
        return false
    end
    local ok, secret = pcall(issecretvalue, value)
    return ok and secret == true
end

function WN:SafeCall(func, ...)
    if type(func) ~= "function" then
        return nil
    end
    local results = { pcall(func, ...) }
    if not results[1] then
        return nil
    end
    table.remove(results, 1)
    return unpack(results)
end

function WN:SafeNumber(value, fallback)
    if type(value) ~= "number" or IsSecret(value) then
        return fallback
    end
    return value
end

function WN:SafeString(value, fallback)
    if type(value) ~= "string" or value == "" or IsSecret(value) then
        return fallback
    end
    return value
end

function WN:SafeBoolean(value, fallback)
    if type(value) ~= "boolean" or IsSecret(value) then
        return fallback
    end
    return value
end

function WN:Clamp(value, minimum, maximum)
    value = tonumber(value) or minimum
    if value < minimum then return minimum end
    if value > maximum then return maximum end
    return value
end

function WN:CopyDefaults(source, destination)
    if type(destination) ~= "table" then destination = {} end
    for key, value in pairs(source) do
        if type(value) == "table" then
            destination[key] = self:CopyDefaults(value, destination[key])
        elseif destination[key] == nil then
            destination[key] = value
        end
    end
    return destination
end

function WN:RegisterLocale(locale, strings)
    self.locales[locale] = strings
end

function WN:GetRequestedLocale()
    local requested = self.db and self.db.settings and self.db.settings.language or "auto"
    if requested == "auto" then
        requested = GetLocale and GetLocale() or "enUS"
    end
    if requested ~= "deDE" and requested ~= "enUS" and requested ~= "enGB" then
        requested = "enUS"
    end
    if requested == "enGB" then requested = "enUS" end
    return requested
end

function WN:ApplyLocale()
    local locale = self:GetRequestedLocale()
    local fallback = self.locales.enUS or {}
    local selected = self.locales[locale] or fallback
    self.activeLocale = locale
    self.L = setmetatable(selected, { __index = fallback })
end

function WN:T(key, ...)
    local text = self.L[key] or key
    if select("#", ...) > 0 then
        local ok, formatted = pcall(string.format, text, ...)
        if ok then return formatted end
    end
    return text
end

function WN:FormatNumber(value, decimals)
    value = self:SafeNumber(value, nil)
    if value == nil then return self:T("NA") end
    decimals = decimals or 0
    if value >= 1000000 then
        return string.format("%.1fM", value / 1000000)
    elseif value >= 1000 then
        return string.format("%.1fK", value / 1000)
    end
    if decimals > 0 then
        return string.format("%." .. decimals .. "f", value)
    end
    return tostring(math.floor(value + 0.5))
end

function WN:FormatPercent(value, decimals)
    value = self:SafeNumber(value, nil)
    if value == nil then return self:T("NA") end
    return string.format("%." .. (decimals or 1) .. "f%%", value)
end

function WN:FormatDuration(seconds)
    seconds = self:SafeNumber(seconds, 0) or 0
    if seconds <= 0 then return self:T("READY") end
    local days = math.floor(seconds / 86400)
    local hours = math.floor((seconds % 86400) / 3600)
    local minutes = math.floor((seconds % 3600) / 60)
    if days > 0 then return string.format("%dd %dh", days, hours) end
    if hours > 0 then return string.format("%dh %02dm", hours, minutes) end
    return string.format("%dm", math.max(1, minutes))
end

function WN:GetCharacterKey()
    return (GetRealmName and GetRealmName() or "?") .. " - " .. (UnitName and UnitName("player") or "?")
end

function WN:GetNowText()
    return date("%H:%M")
end

function WN:Print(message)
    if DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.AddMessage then
        DEFAULT_CHAT_FRAME:AddMessage("|cff12d1d0WoWNext:|r " .. tostring(message))
    end
end

function WN:GetHoverTooltip()
    if not self.hoverTooltip then
        self.hoverTooltip = CreateFrame("GameTooltip", "WoWNextPrivateTooltip", UIParent, "GameTooltipTemplate")
        self.hoverTooltip:SetFrameStrata("TOOLTIP")
    end
    return self.hoverTooltip
end

function WN:PrepareHoverTooltip(owner, anchor)
    local tooltip = self:GetHoverTooltip()
    tooltip:Hide()
    tooltip:SetOwner(owner or UIParent, anchor or "ANCHOR_RIGHT")
    tooltip:ClearLines()
    return tooltip
end

function WN:HideHoverTooltip()
    if self.hoverTooltip then self.hoverTooltip:Hide() end
end

_G.WoWNext = WN
