--[[--------------------------------------------------------------------
  PaladinHolyPower - modules/masque_support.lua
  Masque integration (safe & simple, new API only)
----------------------------------------------------------------------]]

local PHP = _G.PaladinHolyPower
if not PHP then return end

local M = {}
PHP.MasqueSupport = M

-- Parent name shown in Masque's UI (left column). Use runtime addon name if available.
local PARENT_NAME = (PHP.ADDON_NAME or "PaladinHolyPower")

local LibMasque
local ready   = false                    -- true once Masque core is available
local groups  = {}                       -- [key] = Masque group object
local titles  = {}                       -- [key] = subgroup title string
local queue   = {}                       -- [key] = { {btn=, icon=}, ... } until ready
local buttons = setmetatable({}, { __index = function(t, k)
    local w = setmetatable({}, { __mode = "k" }) -- weak-key set
    rawset(t, k, w)
    return w
end })

------------------------------------------------------------------------
-- Internals
------------------------------------------------------------------------

local function safe(fn, ...)
    if fn then pcall(fn, ...) end
end

local function TryReady()
    if ready then return true end
    local LS = _G.LibStub
    if not LS then return false end
    LibMasque = LibMasque or LS("Masque", true)
    if not LibMasque then return false end
    ready = true
    return true
end

local function ensureGroup(key, title)
    if not ready then return nil end
    local g = groups[key]
    if g then return g end
    g = LibMasque:Group(PARENT_NAME, tostring(title or key))
    groups[key] = g
    return g
end

local function flush(key)
    local q = queue[key]
    if not (ready and q) then return end
    local g = ensureGroup(key, titles[key] or key)
    if not g then return end
    for i = 1, #q do
        local it = q[i]
        if it and it.btn and it.icon then
            safe(g.AddButton, g, it.btn, { Icon = it.icon })
            buttons[key][it.btn] = true
        end
    end
    queue[key] = nil
end

------------------------------------------------------------------------
-- Public API
------------------------------------------------------------------------

function M:EnableGroup(key, title)
    if not key then return end
    titles[key] = title or titles[key] or key
    queue[key]  = queue[key] or {}
    if TryReady() then
        ensureGroup(key, titles[key])
        flush(key)
    end
end

function M:AddButton(key, button, iconTexture)
    if not (key and button and iconTexture) then return end
    titles[key] = titles[key] or key
    queue[key]  = queue[key] or {}

    if TryReady() and ensureGroup(key, titles[key]) then
        local g = groups[key]
        safe(g.AddButton, g, button, { Icon = iconTexture })
        buttons[key][button] = true
    else
        table.insert(queue[key], { btn = button, icon = iconTexture })
    end
end

function M:RemoveButton(key, button)
    if not (key and button) then return end
    local g = groups[key]
    if ready and g and buttons[key][button] then
        safe(g.RemoveButton, g, button)
        buttons[key][button] = nil
    end
    -- also remove from queue if it was queued
    local q = queue[key]
    if q then
        for i = #q, 1, -1 do
            if q[i].btn == button then table.remove(q, i) end
        end
    end
end

-- Immediate, synchronous re-skin for a specific group (no timers).
function M:ReskinNow(key)
    if not key then return end
    if not TryReady() then return end
    local g = groups[key]
    if not g then return end
    if queue[key] then flush(key) end
    safe(g.ReSkin, g)  -- newer Masque
    safe(g.Update, g)  -- older Masque
end

-- Friendly aliases
function M:RefreshGroup(key) self:ReskinNow(key) end
function M:UpdateGroup(key)  self:ReskinNow(key) end

-- Optional: reskin every group you’ve created
function M:Update()
    if not TryReady() then return end
    for key, g in pairs(groups) do
        if queue[key] then flush(key) end
        safe(g.ReSkin, g)
        safe(g.Update, g)
    end
end

function M:IsReady() return TryReady() end

-- become ready when core loads; flush any pending
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_LOGIN")
f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", function()
    if TryReady() then
        for key in pairs(queue) do
            ensureGroup(key, titles[key] or key)
            flush(key)
        end
    end
end)

return M