-- Helper: Access config keys from the current skin
local function GetRadioConfig(key, fallback)
    if BuzzerRadioConfig and BuzzerRadioConfig[key] ~= nil then
        return BuzzerRadioConfig[key]
    end
    return fallback
end

function Buzzer_AddButton(frame, buttonSpec)
    local buttonType = buttonSpec.buttonType or "CheckButton"
    local template = buttonSpec.template -- may be nil for raw buttons
    local button = CreateFrame(buttonType, buttonSpec.name or nil, frame, template)

    button:EnableMouse(true)
    button:RegisterForClicks("LeftButtonUp")
    local size = buttonSpec.size or 32
    button:SetSize(size, size)
    button:SetPoint(buttonSpec.point or "TOPLEFT", frame, buttonSpec.relativePoint or "TOPLEFT", buttonSpec.x or 0, buttonSpec.y or 0)

    button:SetFrameLevel((frame:GetFrameLevel() or 1) + 5)

    -- Manually clear Blizzard's default check highlight
    for _, region in ipairs({ button:GetRegions() }) do
        if region:IsObjectType("Texture") and region:GetDrawLayer() == "HIGHLIGHT" then
            region:Hide()
        end
    end

    -- Optional background texture (lowest layer)
    if buttonSpec.background then
        local bgTex = button:CreateTexture(nil, "BACKGROUND")
        bgTex:SetAllPoints(button)
        bgTex:SetTexture(buttonSpec.background)
        button.bgTexture = bgTex
    end

    -- Main button texture
    if buttonSpec.texture and not buttonSpec.background then
        local normalTex = button:CreateTexture(nil, "ARTWORK")
        normalTex:SetAllPoints(button)
        normalTex:SetTexture(buttonSpec.texture)
        button:SetNormalTexture(normalTex)
    elseif buttonSpec.name and buttonSpec.name:find("ChannelButton") then
        local normalTex = button:CreateTexture(nil, "ARTWORK")
        normalTex:SetAllPoints(button)
        normalTex:SetColorTexture(1, 1, 1, 0)
        button:SetNormalTexture(normalTex)
    else
        local fallbackTex = button:CreateTexture(nil, "ARTWORK")
        fallbackTex:SetAllPoints(button)
        fallbackTex:SetColorTexture(0.2, 0.2, 0.2, 0.5)
        button:SetNormalTexture(fallbackTex)
    end

    -- Highlight texture (only if explicitly provided)
    if buttonSpec.highlight then
        local hl = button:CreateTexture(nil, "HIGHLIGHT")
        hl:SetAllPoints(button)
        hl:SetTexture(buttonSpec.highlight)
        button:SetHighlightTexture(hl)
    end

    -- Pushed texture
    if buttonSpec.pushed then
        button:SetPushedTexture(buttonSpec.pushed)
    else
        local pushedTex = button:CreateTexture(nil, "OVERLAY")
        pushedTex:SetAllPoints(button)
        pushedTex:SetColorTexture(1, 1, 1, 0)
        button:SetPushedTexture(pushedTex)
    end

    -- Overlay label
    if buttonSpec.labelText then
        local label = button:CreateFontString(nil, "OVERLAY", buttonSpec.labelFont or "GameFontNormalLarge")
        label:SetPoint("CENTER", button, "CENTER", buttonSpec.labelX or 0, buttonSpec.labelY or 0)
        label:SetText(buttonSpec.labelText)
        label:SetTextColor(unpack(buttonSpec.labelColor or { 1, 0.82, 0 }))
        button.iconText = label
    end

    -- Tooltip
    if buttonSpec.tooltip then
        button:SetScript("OnEnter", function()
            GameTooltip:SetOwner(button, "ANCHOR_RIGHT")
            GameTooltip:SetText(buttonSpec.tooltip, 1, 1, 1)
            GameTooltip:Show()
        end)
        button:SetScript("OnLeave", GameTooltip_Hide)
    end

    -- Click
    if buttonSpec.onClick then
        button:SetScript("OnClick", buttonSpec.onClick)
    end

    -- Load hook
    if buttonSpec.onLoad then
        buttonSpec.onLoad(button)
    end

    -- Track channel buttons
    if buttonSpec.name and buttonSpec.name:find("ChannelButton") then
        local index = tonumber(buttonSpec.name:match("%d+"))
        if index then
            Buzzer_ChannelButtons = Buzzer_ChannelButtons or {}
            Buzzer_ChannelButtons[index] = button
        end
    end

    return button
end




-- Build radio UI based on model config
function Buzzer_BuildUI(config)
    local frame = config.frame or BuzzerMainFrame

    -- Make the main frame non-interactive, but KEEP it movable for the drag handle to work.
    frame:EnableMouse(false)
    frame:SetMovable(true) -- This line has been changed back to 'true'
    frame:EnableMouseWheel(false)
    frame:SetClampedToScreen(true)

    -- Remove any old background
    if frame.BuzzerBackground then
        frame.BuzzerBackground:Hide()
        frame.BuzzerBackground:SetParent(nil)
        frame.BuzzerBackground = nil
    end

    -- Set main frame size
    local frameWidth = config.width or 256
    local frameHeight = config.height or 384
    frame:SetSize(frameWidth, frameHeight)

    -- Background texture drawn directly on main frame
    local bg = frame:CreateTexture(nil, "BACKGROUND")
    bg:SetTexture(config.background)
    if config.backgroundLayout
        and config.backgroundLayout.mode == "contain"
        and config.backgroundLayout.textureWidth
        and config.backgroundLayout.textureHeight
    then
        local layout = config.backgroundLayout
        local scale = math.min(
            frameWidth / layout.textureWidth,
            frameHeight / layout.textureHeight
        ) * (layout.scale or 1)

        bg:SetSize(layout.textureWidth * scale, layout.textureHeight * scale)
        bg:SetPoint(
            layout.point or "CENTER",
            frame,
            layout.relativePoint or "CENTER",
            layout.x or 0,
            layout.y or 0
        )
    else
        bg:SetAllPoints(frame)
    end
    bg:EnableMouse(false)
    frame.BuzzerBackground = bg

    -- Optional channel display text
    if config.channelDisplay then
        local text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
        text:SetPoint("TOPLEFT", frame, "TOPLEFT", config.channelDisplay.x or 0, config.channelDisplay.y or 0)
        text:SetFont(config.channelDisplay.font or "Fonts\\FRIZQT__.TTF", config.channelDisplay.size or 12, config.channelDisplay.outline or "")
        local r, g, b = unpack(config.channelDisplay.color or { 1, 1, 1 })
        text:SetTextColor(r, g, b)
        text:SetText(tostring(BuzzerSettings.channel or 1))
    end


    -- Drag areas (supports multiple)
    if config.dragAreas then
        for i, area in ipairs(config.dragAreas) do
            local dragger = CreateFrame("Frame", "BuzzerDragger" .. i, frame)
            dragger:SetPoint("TOPLEFT", frame, "TOPLEFT", area.x or 0, area.y or 0)
            dragger:SetSize(area.width or 256, area.height or 32)

            -- Frame level BELOW buttons, ABOVE background
            dragger:SetFrameStrata("MEDIUM")
            dragger:SetFrameLevel(frame:GetFrameLevel() + 2)

            -- Allow dragging
            dragger:EnableMouse(true)
            dragger:RegisterForDrag("LeftButton")
            dragger:SetMovable(true)
            dragger:SetScript("OnDragStart", function() frame:StartMoving() end)
            dragger:SetScript("OnDragStop", function() frame:StopMovingOrSizing() end)

            -- Transparent background so it gets input without blocking other regions
            local tex = dragger:CreateTexture(nil, "BACKGROUND")
            tex:SetAllPoints()
            tex:SetColorTexture(0, 0, 0, 0.01)
            tex:EnableMouse(false)
        end
    end



    -- Buttons (interactive)
    if config.buttons then
        for _, buttonSpec in ipairs(config.buttons) do
            Buzzer_AddButton(frame, buttonSpec)
        end
    end

    -- Sync mute button state if it exists
    local mute = _G["MuteButton"]
    if mute and mute.UpdateIcon then
        mute:UpdateIcon()
    end

    Buzzer_UpdateChannelButtons()

end
