-- [ ORBIT CLASS COLOR RESOLVER ]---------------------------------------------------------------------
local _, Orbit = ...
local Engine = Orbit.Engine
Engine.ClassColor = {}
local CC = Engine.ClassColor

local PREVIEW_PARTY_CLASSES = { "WARRIOR", "PRIEST", "MAGE", "HUNTER", "ROGUE" }

local CLASS_COLOR_DEFAULTS = {
    PRIEST = { r = 0.96, g = 0.96, b = 0.96 },
}

local function GetAccountSetting(key)
    return Orbit.db and Orbit.db.AccountSettings and Orbit.db.AccountSettings[key]
end

local function SetAccountSetting(key, val)
    if not Orbit.db.AccountSettings then Orbit.db.AccountSettings = {} end
    Orbit.db.AccountSettings[key] = val
end

-- Memoized "ClassColor_<CLASS>" keys so the override lookups on the hot per-UNIT_HEALTH text path don't re-concat a string each call.
local _classKey = setmetatable({}, { __index = function(t, cf) local k = "ClassColor_" .. cf; t[cf] = k; return k end })

function CC:GetOverrides(classFile)
    local custom = GetAccountSetting(_classKey[classFile or ""])
    if custom then return { r = custom.r, g = custom.g, b = custom.b, a = 1 } end

    local default = classFile and CLASS_COLOR_DEFAULTS[classFile]
    if default then return { r = default.r, g = default.g, b = default.b, a = 1 } end

    local classColor = classFile and RAID_CLASS_COLORS[classFile]
    if classColor then return { r = classColor.r, g = classColor.g, b = classColor.b, a = 1 } end
    return { r = 1, g = 1, b = 1, a = 1 }
end

function CC:GetOverridesUnpacked(classFile)
    local custom = GetAccountSetting(_classKey[classFile or ""])
    if custom then return custom.r, custom.g, custom.b, 1 end

    local default = classFile and CLASS_COLOR_DEFAULTS[classFile]
    if default then return default.r, default.g, default.b, 1 end

    local classColor = classFile and RAID_CLASS_COLORS[classFile]
    if classColor then return classColor.r, classColor.g, classColor.b, 1 end
    return 1, 1, 1, 1
end

function CC:SetOverride(classFile, colorTable)
    if colorTable then colorTable.type = nil end
    SetAccountSetting(_classKey[classFile], colorTable)
    Orbit.EventBus:Fire("ORBIT_COLORS_CHANGED")
end

function CC:GetCurrentClassColor()
    local _, class = UnitClass("player")
    return self:GetOverrides(class)
end

function CC:GetCurrentClassColorUnpacked()
    local _, class = UnitClass("player")
    return self:GetOverridesUnpacked(class)
end

function CC:ResolveClassColorPin(pin)
    if pin.type == "class" then return self:GetCurrentClassColor() end
    return pin.color
end

function CC:ResolveClassColorPinUnpacked(pin)
    if pin.type == "class" then return self:GetCurrentClassColorUnpacked() end
    return pin.color.r, pin.color.g, pin.color.b, pin.color.a or 1
end

-- Flat-value variant for single-color valueColor swatches stored as { r, g, b, a, type? }.
function CC:ResolveValueUnpacked(raw)
    if not raw then return 1, 1, 1, 1 end
    if raw.type == "class" then
        local r, g, b = self:GetCurrentClassColorUnpacked()
        return r, g, b, raw.a or 1
    end
    return raw.r or 1, raw.g or 1, raw.b or 1, raw.a or 1
end

function CC:GetClassColorForUnit(unit)
    if not unit or not UnitExists(unit) then
        if unit and (unit:match("^boss") or unit:match("^arena")) then return { r = 1, g = 0.1, b = 0.1, a = 1 } end
        if unit and unit:match("^party") then
            local index = tonumber(unit:match("party(%d)")) or 1
            local classFile = PREVIEW_PARTY_CLASSES[(index - 1) % #PREVIEW_PARTY_CLASSES + 1]
            return self:GetOverrides(classFile)
        end
        if unit == "player" then
            local _, classFile = UnitClass("player")
            return self:GetOverrides(classFile)
        end
        return { r = 1, g = 1, b = 1, a = 1 }
    end
    if UnitIsPlayer(unit) then
        local _, classFile = UnitClass(unit)
        return self:GetOverrides(classFile)
    end
    local reaction = UnitReaction(unit, "player")
    if reaction then return Engine.ReactionColor:GetReactionColor(reaction) end
    if UnitIsFriend("player", unit) then return Engine.ReactionColor.COLORS.FRIENDLY end
    if UnitCanAttack("player", unit) then return Engine.ReactionColor.COLORS.HOSTILE end
    return Engine.ReactionColor.COLORS.NEUTRAL
end

function CC:ResolveClassColorPinForUnit(pin, unit)
    if pin.type == "class" then return self:GetClassColorForUnit(unit) end
    return pin.color
end

function CC:ResolveClassColorPinForClass(pin, classFile)
    if pin.type == "class" then return self:GetOverrides(classFile) end
    return pin.color
end

function CC:ResolveClassColorPinForPreview(pin, classFile, reaction)
    if pin.type ~= "class" then return pin.color end
    if classFile then return self:GetOverrides(classFile) end
    if reaction then return Engine.ReactionColor:GetReactionColor(reaction) end
    return { r = 1, g = 1, b = 1, a = 1 }
end
