local ADDON_NAME, ns = ...

-- Make the addon table globally reachable (mixins/config uses _G.PlateOMatic)
_G.PlateOMatic = _G.PlateOMatic or ns

ns.util = ns.util or {}
local U = ns.util

function U.CopyDefaults(src, dst)
    if type(src) ~= "table" then return {} end
    if type(dst) ~= "table" then dst = {} end
    for k, v in pairs(src) do
        if type(v) == "table" then
            dst[k] = U.CopyDefaults(v, dst[k])
        elseif dst[k] == nil then
            dst[k] = v
        end
    end
    return dst
end

function U.IsNameplateUnit(unit)
    return unit and type(unit) == "string" and unit:find("nameplate", 1, true)
end

function U.IsSafeUnit(unit)
    return unit and UnitCanAttack("player", unit)
end

function U.LockAlpha(tex)
    if not tex then return end
    tex:SetAlpha(0)
    tex:Hide()
    if not tex.pomLocked then
        hooksecurefunc(tex, "SetAlpha", function(self, a)
            if a and a > 0 then self:SetAlpha(0) end
        end)
        tex.pomLocked = true
    end
end

function U.KillBlizzard(frame, db)
    if not frame then return end
    local hb = frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)

    if hb and hb.border then U.LockAlpha(hb.border) end
    if frame.HealthBarsContainer and frame.HealthBarsContainer.border then U.LockAlpha(frame.HealthBarsContainer.border) end
    if frame.selectionHighlight then U.LockAlpha(frame.selectionHighlight) end

    if frame.CastBarBorder then U.LockAlpha(frame.CastBarBorder) end
    if frame.CastBarShield then U.LockAlpha(frame.CastBarShield) end

    if frame.name then frame.name:Hide() end
    if frame.level then frame.level:Hide() end
    if hb and hb.text then hb.text:Hide() end

    if db and db.hideClassIcon and frame.classificationIndicator then
        frame.classificationIndicator:Hide()
    end
end

function U.RefreshAllPlates(applyFunc)
    for _, plate in pairs(C_NamePlate.GetNamePlates()) do
        if plate and plate.UnitFrame then
            applyFunc(plate.UnitFrame)
        end
    end
end

function U.MakeBorder(frame, key)
    if frame[key] then return frame[key] end
    local b = {}
    for i=1,4 do
        local t = frame:CreateTexture(nil, "OVERLAY")
        t:SetColorTexture(0,0,0,1)
        b[i] = t
    end
    frame[key] = b
    return b
end

function U.LayoutBorder(borders, anchor, size)
    if not borders or not anchor then return end
    local top, bottom, left, right = borders[1], borders[2], borders[3], borders[4]

    top:ClearAllPoints()
    top:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", -size, 0)
    top:SetPoint("BOTTOMRIGHT", anchor, "TOPRIGHT", size, 0)
    top:SetHeight(size)

    bottom:ClearAllPoints()
    bottom:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", -size, 0)
    bottom:SetPoint("TOPRIGHT", anchor, "BOTTOMRIGHT", size, 0)
    bottom:SetHeight(size)

    left:ClearAllPoints()
    left:SetPoint("TOPRIGHT", anchor, "TOPLEFT", 0, size)
    left:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMLEFT", 0, -size)
    left:SetWidth(size)

    right:ClearAllPoints()
    right:SetPoint("TOPLEFT", anchor, "TOPRIGHT", 0, size)
    right:SetPoint("BOTTOMLEFT", anchor, "BOTTOMRIGHT", 0, -size)
    right:SetWidth(size)
end
