local addonName, BM = ...

BM.WindowTexture = nil
BM.NavLogoTexture = "Interface\\AddOns\\BetterMailbox\\Media\\csr_icon_256.png"
BM.CoinColumn = {
    iconSize = 13,
    goldWidth = 104,
    silverWidth = 30,
    copperWidth = 30,
    displayWidth = 209,
    boxWidth = 220,
    footerOffsetX = 10,
}

BM.Skins = {
    premium = { name = "Premium", accent = { 0.9, 0.69, 0.14, 1 }, accentSoft = { 0.58, 0.45, 0.13, 1 }, border = { 0.12, 0.18, 0.24, 1 }, borderSoft = { 0.085, 0.12, 0.16, 1 }, titleAccent = { 0.95, 0.97, 1, 1 }, titleGlow = { 0.18, 0.28, 0.4, 0.06 } },
    warrior = { name = "Warrior", accent = { 0.78, 0.61, 0.43, 1 }, accentSoft = { 0.55, 0.42, 0.29, 1 }, border = { 0.21, 0.17, 0.13, 1 }, borderSoft = { 0.17, 0.135, 0.1, 1 }, titleAccent = { 0.96, 0.9, 0.82, 1 }, titleGlow = { 0.34, 0.24, 0.15, 0.08 } },
    paladin = { name = "Paladin", accent = { 0.96, 0.55, 0.73, 1 }, accentSoft = { 0.68, 0.37, 0.51, 1 }, border = { 0.24, 0.13, 0.19, 1 }, borderSoft = { 0.18, 0.1, 0.14, 1 }, titleAccent = { 1, 0.9, 0.95, 1 }, titleGlow = { 0.35, 0.16, 0.26, 0.08 } },
    hunter = { name = "Hunter", accent = { 0.67, 0.83, 0.45, 1 }, accentSoft = { 0.48, 0.6, 0.31, 1 }, border = { 0.14, 0.2, 0.11, 1 }, borderSoft = { 0.11, 0.16, 0.09, 1 }, titleAccent = { 0.92, 1, 0.88, 1 }, titleGlow = { 0.18, 0.29, 0.12, 0.08 } },
    rogue = { name = "Rogue", accent = { 1, 0.96, 0.41, 1 }, accentSoft = { 0.72, 0.66, 0.24, 1 }, border = { 0.23, 0.2, 0.08, 1 }, borderSoft = { 0.17, 0.15, 0.06, 1 }, titleAccent = { 1, 0.98, 0.82, 1 }, titleGlow = { 0.36, 0.3, 0.08, 0.08 } },
    priest = { name = "Priest", accent = { 0.96, 0.96, 0.96, 1 }, accentSoft = { 0.72, 0.72, 0.72, 1 }, border = { 0.2, 0.2, 0.22, 1 }, borderSoft = { 0.15, 0.15, 0.17, 1 }, titleAccent = { 1, 1, 1, 1 }, titleGlow = { 0.32, 0.32, 0.36, 0.08 } },
    deathknight = { name = "Death Knight", accent = { 0.77, 0.12, 0.23, 1 }, accentSoft = { 0.51, 0.08, 0.15, 1 }, border = { 0.22, 0.08, 0.11, 1 }, borderSoft = { 0.16, 0.06, 0.08, 1 }, titleAccent = { 1, 0.84, 0.87, 1 }, titleGlow = { 0.36, 0.1, 0.14, 0.08 } },
    shaman = { name = "Shaman", accent = { 0, 0.44, 0.87, 1 }, accentSoft = { 0, 0.3, 0.61, 1 }, border = { 0.08, 0.14, 0.24, 1 }, borderSoft = { 0.06, 0.1, 0.18, 1 }, titleAccent = { 0.86, 0.93, 1, 1 }, titleGlow = { 0.08, 0.2, 0.38, 0.08 } },
    mage = { name = "Mage", accent = { 0.25, 0.78, 0.92, 1 }, accentSoft = { 0.18, 0.56, 0.68, 1 }, border = { 0.08, 0.18, 0.22, 1 }, borderSoft = { 0.06, 0.13, 0.17, 1 }, titleAccent = { 0.88, 0.98, 1, 1 }, titleGlow = { 0.08, 0.26, 0.34, 0.08 } },
    warlock = { name = "Warlock", accent = { 0.53, 0.53, 0.93, 1 }, accentSoft = { 0.38, 0.38, 0.68, 1 }, border = { 0.14, 0.12, 0.24, 1 }, borderSoft = { 0.1, 0.09, 0.18, 1 }, titleAccent = { 0.9, 0.9, 1, 1 }, titleGlow = { 0.16, 0.14, 0.38, 0.08 } },
    monk = { name = "Monk", accent = { 0, 1, 0.6, 1 }, accentSoft = { 0, 0.68, 0.42, 1 }, border = { 0.06, 0.2, 0.15, 1 }, borderSoft = { 0.05, 0.14, 0.11, 1 }, titleAccent = { 0.9, 1, 0.95, 1 }, titleGlow = { 0.06, 0.34, 0.22, 0.08 } },
    druid = { name = "Druid", accent = { 1, 0.49, 0.04, 1 }, accentSoft = { 0.72, 0.34, 0.03, 1 }, border = { 0.24, 0.12, 0.04, 1 }, borderSoft = { 0.17, 0.09, 0.03, 1 }, titleAccent = { 1, 0.9, 0.8, 1 }, titleGlow = { 0.38, 0.18, 0.04, 0.08 } },
    demonhunter = { name = "Demon Hunter", accent = { 0.64, 0.19, 0.79, 1 }, accentSoft = { 0.44, 0.13, 0.55, 1 }, border = { 0.18, 0.08, 0.22, 1 }, borderSoft = { 0.13, 0.06, 0.16, 1 }, titleAccent = { 0.96, 0.86, 1, 1 }, titleGlow = { 0.28, 0.08, 0.34, 0.08 } },
    evoker = { name = "Evoker", accent = { 0.2, 0.58, 0.5, 1 }, accentSoft = { 0.14, 0.4, 0.35, 1 }, border = { 0.08, 0.17, 0.16, 1 }, borderSoft = { 0.06, 0.12, 0.11, 1 }, titleAccent = { 0.86, 0.98, 0.95, 1 }, titleGlow = { 0.08, 0.22, 0.2, 0.08 } },
}

BM.Theme = {
    bg = { 0.02, 0.025, 0.032, 0.992 },
    panel = { 0.045, 0.05, 0.058, 0.975 },
    panelAlt = { 0.055, 0.061, 0.071, 0.985 },
    border = { 0.12, 0.18, 0.24, 1 },
    borderSoft = { 0.085, 0.12, 0.16, 1 },
    accent = { 0.9, 0.69, 0.14, 1 },
    accentSoft = { 0.58, 0.45, 0.13, 1 },
    accentGlow = { 0.22, 0.32, 0.42, 0.045 },
    text = { 0.88, 0.91, 0.96, 1 },
    mutetext = { 0.54, 0.61, 0.7, 1 },
    success = { 0.55, 0.86, 0.52, 1 },
    danger = { 1, 0.4, 0.36, 1 },
    headerLine = { 0.11, 0.19, 0.27, 0.95 },
    titleAccent = { 0.95, 0.97, 1, 1 },
    titleGlow = { 0.18, 0.28, 0.4, 0.06 },
    ornament = { 0.03, 0.05, 0.08, 0.14 },
    ornamentSoft = { 0.02, 0.04, 0.06, 0.18 },
    footer = { 0.035, 0.04, 0.048, 0.985 },
    metric = { 0.035, 0.04, 0.048, 0.985 },
    hero = { 0.035, 0.04, 0.048, 0.985 },
    settings = { 0.058, 0.065, 0.08, 0.965 },
    input = { 0.032, 0.038, 0.05, 0.98 },
    inputBorder = { 0.12, 0.18, 0.24, 1 },
}

function BM:GetSkin()
    BetterMailboxDB = BetterMailboxDB or {}
    local key = BetterMailboxDB.skin or "premium"
    return BM.Skins[key] and key or "premium"
end

function BM:GetSkinDisplay()
    local skin = BM.Skins[BM:GetSkin()] or BM.Skins.premium
    return skin.name
end

function BM:GetSkinColorizedName(key)
    local skin = BM.Skins[key or BM:GetSkin()] or BM.Skins.premium
    local r = math.floor((skin.accent[1] or 1) * 255 + 0.5)
    local g = math.floor((skin.accent[2] or 1) * 255 + 0.5)
    local b = math.floor((skin.accent[3] or 1) * 255 + 0.5)
    return string.format("|cff%02x%02x%02x%s|r", r, g, b, skin.name)
end

function BM:GetSkinAssets()
    return {}
end

function BM:SetSkin()
    if BM.ApplyCurrentSkin then
        BM:ApplyCurrentSkin()
    end
end

function BM:ApplySkinTheme()
    local skin = BM.Skins[BM:GetSkin()] or BM.Skins.premium
    BM.Theme.accent = { unpack(skin.accent) }
    BM.Theme.accentSoft = { unpack(skin.accentSoft) }
    BM.Theme.border = { unpack(skin.border) }
    BM.Theme.borderSoft = { unpack(skin.borderSoft) }
    BM.Theme.titleAccent = { unpack(skin.titleAccent) }
    BM.Theme.titleGlow = { skin.accent[1], skin.accent[2], skin.accent[3], 0.12 }
    BM.Theme.accentGlow = { skin.accent[1], skin.accent[2], skin.accent[3], 0.12 }
    BM.Theme.headerLine = { skin.border[1], skin.border[2], skin.border[3], 0.95 }
    BM.Theme.inputBorder = { unpack(skin.border) }
    BM.Theme.text = {
        math.min(1, skin.accent[1] * 1.15 + 0.08),
        math.min(1, skin.accent[2] * 1.15 + 0.08),
        math.min(1, skin.accent[3] * 1.15 + 0.08),
        1,
    }
    BM.Theme.mutetext = {
        math.min(1, skin.accent[1] * 0.95 + 0.24),
        math.min(1, skin.accent[2] * 0.95 + 0.24),
        math.min(1, skin.accent[3] * 0.95 + 0.24),
        1,
    }
end

function BM:ApplyThemeToPanel(panel)
    if not panel or not panel.SetBackdropColor then return end
    local palette = panel.themePalette and BM.Theme[panel.themePalette] or BM.Theme.panel
    panel:SetBackdropColor(unpack(palette))
    panel:SetBackdropBorderColor(unpack(BM.Theme.border))
    if panel.shadow then panel.shadow:SetVertexColor(unpack(BM.Theme.accentGlow)) end
    if panel.accent then panel.accent:SetVertexColor(unpack(BM.Theme.accent)) end

    if panel.shadow then panel.shadow:SetAlpha(0.22) end
    if panel.accent then panel.accent:SetAlpha(0.12) end
end

function BM:ApplyThemeToButton(button)
    if not button then return end
    if button.label then
        button.label:SetTextColor(unpack(BM.Theme.text))
    end
    if button.ApplyVisualState then
        if button.style == "tab" and button.tabKey == BM.currentTab then
            button:ApplyVisualState("active")
        else
            button:ApplyVisualState("normal")
        end
    end
end

function BM:CreatePanel(parent, inset)
    local panel = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    panel:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Buttons/WHITE8X8",
        edgeSize = 1,
        insets = inset or { left = 1, right = 1, top = 1, bottom = 1 },
    })
    panel.shadow = panel:CreateTexture(nil, "BACKGROUND", nil, -7)
    panel.shadow:SetTexture("Interface/Buttons/WHITE8X8")
    panel.shadow:SetPoint("TOPLEFT", -1, 1)
    panel.shadow:SetPoint("BOTTOMRIGHT", 1, -1)

    panel.accent = panel:CreateTexture(nil, "ARTWORK")
    panel.accent:SetTexture("Interface/Buttons/WHITE8X8")
    panel.accent:SetPoint("TOPLEFT", 0, 0)
    panel.accent:SetPoint("TOPRIGHT", 0, 0)
    panel.accent:SetHeight(1)
    BM.ThemedPanels = BM.ThemedPanels or {}
    table.insert(BM.ThemedPanels, panel)
    BM:ApplyThemeToPanel(panel)

    return panel
end

function BM:SkinButton(button, width, height, label, style)
    button:SetSize(width, height)

    if not button.bg then
        button.bg = CreateFrame("Frame", nil, button, "BackdropTemplate")
        button.bg:SetFrameLevel(math.max(0, button:GetFrameLevel() - 1))
        button.bg:SetAllPoints()
        button.bg:SetBackdrop({
            bgFile = "Interface/Buttons/WHITE8X8",
            edgeFile = "Interface/Buttons/WHITE8X8",
            edgeSize = 1,
        })

        button.topGlow = button.bg:CreateTexture(nil, "ARTWORK")
        button.topGlow:SetTexture("Interface/Buttons/WHITE8X8")
        button.topGlow:SetPoint("TOPLEFT", 1, -1)
        button.topGlow:SetPoint("TOPRIGHT", -1, -1)
        button.topGlow:SetHeight(math.max(4, math.floor(height * 0.18)))

        button.bottomAccent = button.bg:CreateTexture(nil, "ARTWORK")
        button.bottomAccent:SetTexture("Interface/Buttons/WHITE8X8")
        button.bottomAccent:SetPoint("BOTTOMLEFT", 1, 1)
        button.bottomAccent:SetPoint("BOTTOMRIGHT", -1, 1)
        button.bottomAccent:SetHeight(math.max(2, math.floor(height * 0.12)))

        button.hoverGlow = button.bg:CreateTexture(nil, "ARTWORK")
        button.hoverGlow:SetTexture("Interface/Buttons/WHITE8X8")
        button.hoverGlow:SetPoint("TOPLEFT", -2, 2)
        button.hoverGlow:SetPoint("BOTTOMRIGHT", 2, -2)
        button.hoverGlow:SetAlpha(0)

        button.art = button.bg:CreateTexture(nil, "ARTWORK", nil, -1)
        button.art:SetPoint("TOPLEFT", -6, 2)
        button.art:SetPoint("BOTTOMRIGHT", 6, -2)
        button.art:SetAlpha(0)

        button.label = button:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        button.label:SetPoint("CENTER", 0, 0)

        button.accentFill = button.bg:CreateTexture(nil, "ARTWORK", nil, -1)
        button.accentFill:SetTexture("Interface/Buttons/WHITE8X8")
        button.accentFill:SetPoint("TOPLEFT", 1, -1)
        button.accentFill:SetPoint("BOTTOMRIGHT", -1, 1)
        button.accentFill:Hide()

        button.highlight = button:CreateTexture(nil, "HIGHLIGHT")
        button.highlight:SetTexture("Interface/Buttons/WHITE8X8")
        button.highlight:SetAllPoints()
        button.highlight:SetBlendMode("ADD")
        button.highlight:SetAlpha(0)
    end

    BM.ThemedButtons = BM.ThemedButtons or {}
    if not button.BetterMailboxThemeRegistered then
        table.insert(BM.ThemedButtons, button)
        button.BetterMailboxThemeRegistered = true
    end

    button.style = style or "default"
    button.label:SetText(label or "")
    button.label:SetTextColor(unpack(BM.Theme.text))

    local function applyState(state)
        if button.art then
            button.art:SetTexture(nil)
            button.art:Hide()
        end

        if button.style == "tab" then
            if state == "active" then
                button.bg:SetBackdropColor(0.06, 0.085, 0.13, 0.995)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.accent))
                button.topGlow:SetVertexColor(unpack(BM.Theme.accent))
                if button.hoverGlow then
                    button.hoverGlow:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.28)
                    button.hoverGlow:SetAlpha(1)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(unpack(BM.Theme.accent))
                    button.bottomAccent:SetAlpha(1)
                end
                if button.accentFill then
                    button.accentFill:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.26)
                    button.accentFill:Show()
                end
                if button.highlight then
                    button.highlight:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.18)
                    button.highlight:SetAlpha(1)
                end
                if button.label then button.label:SetTextColor(1, 1, 1) end
            elseif state == "hover" then
                button.bg:SetBackdropColor(0.08, 0.12, 0.18, 0.995)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.accent))
                button.topGlow:SetVertexColor(unpack(BM.Theme.accent))
                if button.hoverGlow then
                    button.hoverGlow:SetVertexColor(0.2, 0.45, 0.9, 0.36)
                    button.hoverGlow:SetAlpha(1)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(unpack(BM.Theme.accent))
                    button.bottomAccent:SetAlpha(1)
                end
                if button.accentFill then
                    button.accentFill:SetVertexColor(0.2, 0.45, 0.9, 0.3)
                    button.accentFill:Show()
                end
                if button.highlight then
                    button.highlight:SetVertexColor(0.2, 0.45, 0.9, 0.28)
                    button.highlight:SetAlpha(1)
                end
                if button.label then button.label:SetTextColor(1, 1, 1) end
            else
                button.bg:SetBackdropColor(0.012, 0.016, 0.022, 0.98)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))
                button.topGlow:SetVertexColor(0.07, 0.1, 0.15, 0.16)
                if button.hoverGlow then
                    button.hoverGlow:SetAlpha(0)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(0.08, 0.11, 0.16, 0.24)
                    button.bottomAccent:SetAlpha(0.55)
                end
                if button.accentFill then
                    button.accentFill:Hide()
                end
                if button.highlight then
                    button.highlight:SetAlpha(0)
                end
                if button.label then button.label:SetTextColor(unpack(BM.Theme.text)) end
            end
        else
            if state == "hover" then
                button.bg:SetBackdropColor(0.08, 0.12, 0.18, 0.995)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.accent))
                button.topGlow:SetVertexColor(unpack(BM.Theme.accent))
                if button.hoverGlow then
                    button.hoverGlow:SetVertexColor(0.2, 0.45, 0.9, 0.38)
                    button.hoverGlow:SetAlpha(1)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(unpack(BM.Theme.accent))
                    button.bottomAccent:SetAlpha(1)
                end
                if button.accentFill then
                    button.accentFill:SetVertexColor(0.2, 0.45, 0.9, 0.3)
                    button.accentFill:Show()
                end
                if button.highlight then
                    button.highlight:SetVertexColor(0.2, 0.45, 0.9, 0.34)
                    button.highlight:SetAlpha(1)
                end
                if button.label then button.label:SetTextColor(1, 1, 1) end
            elseif state == "pressed" then
                button.bg:SetBackdropColor(0.034, 0.045, 0.06, 0.99)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.accentSoft))
                button.topGlow:SetVertexColor(unpack(BM.Theme.accentSoft))
                if button.hoverGlow then
                    button.hoverGlow:SetVertexColor(0.2, 0.45, 0.9, 0.24)
                    button.hoverGlow:SetAlpha(1)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(unpack(BM.Theme.accentSoft))
                    button.bottomAccent:SetAlpha(0.75)
                end
                if button.accentFill then
                    button.accentFill:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.08)
                    button.accentFill:Show()
                end
                if button.highlight then
                    button.highlight:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.18)
                    button.highlight:SetAlpha(1)
                end
                if button.label then button.label:SetTextColor(unpack(BM.Theme.text)) end
            else
                button.bg:SetBackdropColor(0.032, 0.038, 0.046, 0.98)
                button.bg:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))
                button.topGlow:SetVertexColor(0.1, 0.14, 0.18, 0.14)
                if button.hoverGlow then
                    button.hoverGlow:SetAlpha(0)
                end
                if button.bottomAccent then
                    button.bottomAccent:SetVertexColor(0.09, 0.12, 0.18, 0.2)
                    button.bottomAccent:SetAlpha(0.5)
                end
                if button.accentFill then
                    button.accentFill:Hide()
                end
                if button.highlight then
                    button.highlight:SetAlpha(0)
                end
                if button.label then button.label:SetTextColor(unpack(BM.Theme.text)) end
            end
        end
    end

    button.ApplyVisualState = applyState
    applyState("normal")

    button:SetScript("OnMouseDown", function(self)
        if self.ApplyVisualState then self:ApplyVisualState("pressed") end
    end)
    button:SetScript("OnMouseUp", function(self)
        if self.ApplyVisualState then self:ApplyVisualState("hover") end
    end)
    button:SetScript("OnEnter", function(self)
        if self.ApplyVisualState then self:ApplyVisualState("hover") end
    end)
    button:SetScript("OnLeave", function(self)
        if self.ApplyVisualState then
            if self.style == "tab" and self.tabKey == BM.currentTab then
                self:ApplyVisualState("active")
            else
                self:ApplyVisualState("normal")
            end
        end
    end)
end

function BM:CreateFlatActionButton(parent, width, height, label, style)
    local button = CreateFrame("Button", nil, parent)
    BM:SkinButton(button, width, height, label, style)
    return button
end

function BM:CreateTabButton(parent, text, key)
    local button = BM:CreateFlatActionButton(parent, 172, 38, text, "tab")
    button.tabKey = key
    button:SetScript("OnClick", function(self)
        BM:SelectTab(self.tabKey)
    end)
    return button
end

function BM:RefreshMetricLayout()
    if not BM.MetricPanel then return end

    local layout = BM.InboxLayoutMetrics or {}
    local goldBoxWidth = layout.goldBoxWidth or BM.CoinColumn.boxWidth
    local goldLeftX = (layout.goldLeftX or math.max(0, (BM.MetricPanel:GetWidth() or 0) - goldBoxWidth - 26)) + (BM.CoinColumn.footerOffsetX or 0)

    if BM.MetricInboxCard and BM.InboxCountLabel and BM.MetricInboxCount then
        local labelWidth = math.max(64, math.ceil(BM.InboxCountLabel:GetUnboundedStringWidth()) + 4)
        local valueWidth = math.max(26, math.ceil(BM.MetricInboxCount:GetUnboundedStringWidth()) + 6)
        BM.MetricInboxCard:SetWidth(labelWidth + valueWidth + 16)
        BM.InboxCountLabel:SetWidth(labelWidth)
        BM.MetricInboxCount:SetWidth(valueWidth)
    end

    if BM.MetricLootCard and BM.LootLabel and BM.MetricLootCount then
        local labelWidth = math.max(64, math.ceil(BM.LootLabel:GetUnboundedStringWidth()) + 4)
        local valueWidth = math.max(26, math.ceil(BM.MetricLootCount:GetUnboundedStringWidth()) + 6)
        BM.MetricLootCard:SetWidth(labelWidth + valueWidth + 16)
        BM.LootLabel:SetWidth(labelWidth)
        BM.MetricLootCount:SetWidth(valueWidth)
    end

    if BM.MetricLootCard and BM.MetricInboxCard then
        BM.MetricLootCard:ClearAllPoints()
        BM.MetricLootCard:SetPoint("LEFT", BM.MetricInboxCard, "RIGHT", 28, 0)
    end

    if BM.MetricGoldCard then
        BM.MetricGoldCard:SetWidth(math.max(170, goldBoxWidth))
        BM.MetricGoldCard:ClearAllPoints()
        BM.MetricGoldCard:SetPoint("LEFT", BM.MetricPanel, "LEFT", goldLeftX, 0)
    end

    if BM.GoldLabel and BM.MetricGoldCard then
        BM.GoldLabel:ClearAllPoints()
        BM.GoldLabel:SetPoint("RIGHT", BM.MetricGoldCard, "LEFT", -12, 0)
        BM.GoldLabel:SetWidth(math.max(140, math.ceil(BM.GoldLabel:GetUnboundedStringWidth()) + 8))
        BM.GoldLabel:SetJustifyH("RIGHT")
    end

    if BM.MetricGoldCoinDisplay and BM.MetricGoldCard then
        BM.MetricGoldCoinDisplay:ClearAllPoints()
        BM.MetricGoldCoinDisplay:SetPoint("CENTER", BM.MetricGoldCard, "CENTER", 0, 0)
        BM.MetricGoldCoinDisplay:SetWidth(layout.coinDisplayWidth or BM.CoinColumn.displayWidth)
        if BM.MetricGoldCoinDisplay.Gold then
            BM.MetricGoldCoinDisplay.Gold:SetWidth(BM.CoinColumn.goldWidth)
            BM.MetricGoldCoinDisplay.Silver:SetWidth(BM.CoinColumn.silverWidth)
            BM.MetricGoldCoinDisplay.Copper:SetWidth(BM.CoinColumn.copperWidth)
        end
    end
end

function BM:SetStatus(text, r, g, b)
    if BM.StatusText then
        BM.StatusText:SetText(text or "")
        BM.StatusText:SetTextColor(r or BM.Theme.mutetext[1], g or BM.Theme.mutetext[2], b or BM.Theme.mutetext[3])
    end
end

function BM:UpdateTabButtons()
    if not BM.TabButtons then return end
    for _, button in ipairs(BM.TabButtons) do
        if button.tabKey == BM.currentTab and button.ApplyVisualState then
            button:ApplyVisualState("active")
        elseif button.ApplyVisualState then
            button:ApplyVisualState("normal")
        end
    end
end

function BM:SelectTab(tabKey)
    BM.currentTab = tabKey or "inbox"

    if BM.InboxPanel then BM.InboxPanel:SetShown(BM.currentTab == "inbox") end
    if BM.SendPanel then BM.SendPanel:SetShown(BM.currentTab == "send") end
    if BM.OptionsPanel then BM.OptionsPanel:SetShown(BM.currentTab == "options") end
    if BM.MetricPanel then BM.MetricPanel:SetShown(BM.currentTab == "inbox") end
    if BM.ActionBar then BM.ActionBar:SetShown(BM.currentTab == "inbox") end

    BM:UpdateTabButtons()

    if BM.currentTab == "inbox" then
        if BM.RefreshInbox then BM:RefreshInbox() end
    elseif BM.currentTab == "send" then
        BM:SetStatus(BM:L("compose_status"), unpack(BM.Theme.mutetext))
    else
        BM:SetStatus(BM:L("options"), unpack(BM.Theme.mutetext))
    end
end

function BM:CreateInput(parent, width, height, multiline)
    local holder = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    holder:SetSize(width, height)
    holder:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Buttons/WHITE8X8",
        edgeSize = 1,
    })
    BM.ThemedInputs = BM.ThemedInputs or {}
    table.insert(BM.ThemedInputs, holder)
    holder:SetBackdropColor(unpack(BM.Theme.input))
    holder:SetBackdropBorderColor(unpack(BM.Theme.inputBorder))

    if multiline then
        local edit = CreateFrame("EditBox", nil, holder)
        edit:SetMultiLine(true)
        edit:SetFontObject("ChatFontNormal")
        edit:SetAutoFocus(false)
        edit:EnableMouse(true)
        edit:SetPoint("TOPLEFT", 10, -10)
        edit:SetPoint("BOTTOMRIGHT", -10, 10)
        edit:SetTextInsets(4, 4, 4, 4)
        edit:SetTextColor(0.92, 0.95, 1)
        edit:SetJustifyH("LEFT")
        edit:SetJustifyV("TOP")
        edit:SetScript("OnEscapePressed", edit.ClearFocus)
        edit:SetScript("OnMouseDown", function(self)
            self:SetFocus()
        end)
        holder.EditBox = edit
    else
        local edit = CreateFrame("EditBox", nil, holder)
        edit:SetPoint("TOPLEFT", 10, -8)
        edit:SetPoint("BOTTOMRIGHT", -10, 8)
        edit:SetAutoFocus(false)
        edit:SetFontObject("GameFontHighlight")
        edit:SetTextColor(0.92, 0.95, 1)
        edit:SetScript("OnEscapePressed", edit.ClearFocus)
        holder.EditBox = edit
    end

    return holder
end

function BM:CreateMainFrame()
    local f = CreateFrame("Frame", "BetterMailboxFrame", UIParent, "BackdropTemplate")
    f:SetSize(1360, 920)
    f:SetPoint("CENTER")
    f:SetFrameStrata("DIALOG")
    f:SetToplevel(true)
    f:Raise()
    f:SetClampedToScreen(true)
    f:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Buttons/WHITE8X8",
        edgeSize = 1,
    })
    f:SetBackdropColor(unpack(BM.Theme.bg))
    f:SetBackdropBorderColor(0.08, 0.11, 0.15, 1)

    local outerGlow = f:CreateTexture(nil, "BACKGROUND", nil, -8)
    outerGlow:SetTexture("Interface/Buttons/WHITE8X8")
    outerGlow:SetPoint("TOPLEFT", -2, 2)
    outerGlow:SetPoint("BOTTOMRIGHT", 2, -2)
    outerGlow:SetVertexColor(unpack(BM.Theme.accentGlow))

    local windowArt = f:CreateTexture(nil, "BACKGROUND", nil, -6)
    windowArt:SetAllPoints()
    windowArt:SetAlpha(0)

    local frameOrnamentTop = f:CreateTexture(nil, "BACKGROUND", nil, -3)
    frameOrnamentTop:SetTexture("Interface/Buttons/WHITE8X8")
    frameOrnamentTop:SetPoint("TOPLEFT", 22, -18)
    frameOrnamentTop:SetPoint("TOPRIGHT", -22, -18)
    frameOrnamentTop:SetHeight(110)
    frameOrnamentTop:SetVertexColor(unpack(BM.Theme.ornament))
    frameOrnamentTop:SetAlpha(0)

    local frameOrnamentBottom = f:CreateTexture(nil, "BACKGROUND", nil, -3)
    frameOrnamentBottom:SetTexture("Interface/Buttons/WHITE8X8")
    frameOrnamentBottom:SetPoint("BOTTOMLEFT", 22, 18)
    frameOrnamentBottom:SetPoint("BOTTOMRIGHT", -22, 18)
    frameOrnamentBottom:SetHeight(80)
    frameOrnamentBottom:SetVertexColor(unpack(BM.Theme.ornamentSoft))
    frameOrnamentBottom:SetAlpha(0)

    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", function(self)
        self:Raise()
        self:StartMoving()
    end)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)
    f:Hide()

    local header = BM:CreatePanel(f)
    header:SetPoint("TOPLEFT", 16, -16)
    header:SetPoint("TOPRIGHT", -16, -16)
    header:SetHeight(82)
    header.themePalette = "hero"
    BM:ApplyThemeToPanel(header)

    local headerGlow = header:CreateTexture(nil, "BACKGROUND", nil, -2)
    headerGlow:SetTexture("Interface/Buttons/WHITE8X8")
    headerGlow:SetPoint("TOPLEFT", 1, -1)
    headerGlow:SetPoint("TOPRIGHT", -1, -1)
    headerGlow:SetHeight(18)
    headerGlow:SetVertexColor(unpack(BM.Theme.titleGlow))

    local headerRuneLeft = header:CreateTexture(nil, "ARTWORK")
    headerRuneLeft:SetTexture("Interface/Buttons/WHITE8X8")
    headerRuneLeft:SetPoint("TOPLEFT", 18, -16)
    headerRuneLeft:SetSize(86, 2)
    headerRuneLeft:SetVertexColor(unpack(BM.Theme.accent))

    local headerRuneRight = header:CreateTexture(nil, "ARTWORK")
    headerRuneRight:SetTexture("Interface/Buttons/WHITE8X8")
    headerRuneRight:SetPoint("TOPRIGHT", -18, -16)
    headerRuneRight:SetSize(140, 2)
    headerRuneRight:SetVertexColor(unpack(BM.Theme.accent))

    local headerArt = header:CreateTexture(nil, "BACKGROUND")
    headerArt:SetPoint("TOPLEFT", 18, -10)
    headerArt:SetPoint("TOPRIGHT", -18, -10)
    headerArt:SetHeight(64)
    headerArt:SetAlpha(0)

    local logo = header:CreateTexture(nil, "ARTWORK")
    logo:SetPoint("LEFT", 24, -2)
    logo:SetSize(60, 60)
    logo:SetTexture(BM.NavLogoTexture)

    local logoGlow = header:CreateTexture(nil, "BACKGROUND")
    logoGlow:SetTexture("Interface/Buttons/WHITE8X8")
    logoGlow:SetPoint("CENTER", logo, "CENTER")
    logoGlow:SetSize(70, 70)
    logoGlow:SetVertexColor(unpack(BM.Theme.titleGlow))

    local title = header:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", logo, "TOPRIGHT", 16, -12)
    title:SetTextColor(unpack(BM.Theme.titleAccent))

    local kicker = header:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    kicker:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
    kicker:SetTextColor(unpack(BM.Theme.accent))
    kicker:SetText("PREMIUM MAIL SUITE")

    local subtitle = header:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    subtitle:SetPoint("TOPLEFT", kicker, "BOTTOMLEFT", 0, -4)
    subtitle:SetTextColor(unpack(BM.Theme.mutetext))

    local heroMeta = header:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    heroMeta:SetPoint("RIGHT", header, "RIGHT", -110, -2)
    heroMeta:SetTextColor(unpack(BM.Theme.mutetext))
    heroMeta:SetText("ElvUI mail flow")

    local brandLine = header:CreateTexture(nil, "ARTWORK")
    brandLine:SetTexture("Interface/Buttons/WHITE8X8")
    brandLine:SetPoint("BOTTOMLEFT", 18, 10)
    brandLine:SetPoint("BOTTOMRIGHT", -18, 10)
    brandLine:SetHeight(1)
    brandLine:SetVertexColor(unpack(BM.Theme.headerLine))

    local topButtons = CreateFrame("Frame", nil, header)
    topButtons:SetPoint("TOPRIGHT", -18, -14)
    topButtons:SetSize(94, 28)

    local close = BM:CreateFlatActionButton(topButtons, 34, 24, "X")
    close:SetPoint("RIGHT", 0, 0)
    close:SetScript("OnClick", function()
        BM:HideUI()
        CloseMail()
    end)

    local optionsButton = BM:CreateFlatActionButton(topButtons, 34, 24, "G")
    optionsButton:SetPoint("RIGHT", close, "LEFT", -8, 0)
    optionsButton:SetScript("OnClick", function()
        BM:SelectTab("options")
    end)
    optionsButton.label:SetText("")
    optionsButton.icon = optionsButton:CreateTexture(nil, "OVERLAY")
    optionsButton.icon:SetTexture("Interface/Buttons/UI-OptionsButton")
    optionsButton.icon:SetSize(16, 16)
    optionsButton.icon:SetPoint("CENTER")

    local navShell = BM:CreatePanel(f)
    navShell:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -10)
    navShell:SetSize(392, 54)
    navShell.themePalette = "panelAlt"
    BM:ApplyThemeToPanel(navShell)

    local navBar = CreateFrame("Frame", nil, navShell)
    navBar:SetPoint("TOPLEFT", 10, -8)
    navBar:SetPoint("BOTTOMRIGHT", -10, 8)

    local inboxTab = BM:CreateTabButton(navBar, "", "inbox")
    inboxTab:SetPoint("LEFT", 2, 0)

    local sendTab = BM:CreateTabButton(navBar, "", "send")
    sendTab:SetPoint("LEFT", inboxTab, "RIGHT", 10, 0)

    local metrics = BM:CreatePanel(f)
    metrics:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -10)
    metrics:SetSize(360, 24)
    metrics.themePalette = "metric"
    BM:ApplyThemeToPanel(metrics)

    local function CreateMetricCoinDisplay(parent)
        local frame = CreateFrame("Frame", nil, parent)
        frame:SetSize(BM.CoinColumn.displayWidth, 16)

        local copperIcon = frame:CreateTexture(nil, "OVERLAY")
        copperIcon:SetTexture("Interface\\MoneyFrame\\UI-CopperIcon")
        copperIcon:SetSize(BM.CoinColumn.iconSize, BM.CoinColumn.iconSize)
        copperIcon:SetPoint("RIGHT", 0, -1)

        local copper = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        copper:SetPoint("RIGHT", copperIcon, "LEFT", -2, 0)
        copper:SetWidth(BM.CoinColumn.copperWidth)
        copper:SetJustifyH("RIGHT")
        copper:SetWordWrap(false)

        local silverIcon = frame:CreateTexture(nil, "OVERLAY")
        silverIcon:SetTexture("Interface\\MoneyFrame\\UI-SilverIcon")
        silverIcon:SetSize(BM.CoinColumn.iconSize, BM.CoinColumn.iconSize)
        silverIcon:SetPoint("RIGHT", copper, "LEFT", -4, -1)

        local silver = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        silver:SetPoint("RIGHT", silverIcon, "LEFT", -2, 0)
        silver:SetWidth(BM.CoinColumn.silverWidth)
        silver:SetJustifyH("RIGHT")
        silver:SetWordWrap(false)

        local goldIcon = frame:CreateTexture(nil, "OVERLAY")
        goldIcon:SetTexture("Interface\\MoneyFrame\\UI-GoldIcon")
        goldIcon:SetSize(BM.CoinColumn.iconSize, BM.CoinColumn.iconSize)
        goldIcon:SetPoint("RIGHT", silver, "LEFT", -4, -1)

        local gold = frame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        gold:SetPoint("RIGHT", goldIcon, "LEFT", -2, 0)
        gold:SetWidth(BM.CoinColumn.goldWidth)
        gold:SetJustifyH("RIGHT")
        gold:SetWordWrap(false)

        frame.Gold = gold
        frame.Silver = silver
        frame.Copper = copper
        frame.GoldIcon = goldIcon
        frame.SilverIcon = silverIcon
        frame.CopperIcon = copperIcon

        return frame
    end

    local function CreateMetricCard(parent, anchor, offsetX)
        local card = CreateFrame("Frame", nil, parent, "BackdropTemplate")
        card:SetSize(112, 22)
        if anchor then
            card:SetPoint("LEFT", anchor, "RIGHT", offsetX or 10, 0)
        else
            card:SetPoint("LEFT", 10, 0)
        end
        card:SetBackdrop({
            bgFile = "Interface/Buttons/WHITE8X8",
            edgeFile = "Interface/Buttons/WHITE8X8",
            edgeSize = 1,
        })
        card:SetBackdropColor(unpack(BM.Theme.bg))
        card:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))

        local label = card:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        label:SetPoint("LEFT", 8, 0)
        label:SetTextColor(unpack(BM.Theme.mutetext))
        label:SetJustifyH("LEFT")
        label:SetWidth(46)
        label:SetWordWrap(false)

        local value = card:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        value:SetPoint("RIGHT", card, "RIGHT", -8, 0)
        value:SetTextColor(unpack(BM.Theme.text))
        value:SetJustifyH("RIGHT")
        value:SetWidth(54)
        value:SetWordWrap(false)

        card.Label = label
        card.Value = value

        return card, label, value
    end

    local inboxCard, inboxCountLabel, inboxCountValue = CreateMetricCard(metrics, nil)
    local lootCard, lootLabel, lootValue = CreateMetricCard(metrics, inboxCard, 12)
    local goldCard, goldLabel, goldValue = CreateMetricCard(metrics, lootCard, 12)
    goldValue:Hide()
    local goldCoinDisplay = CreateMetricCoinDisplay(goldCard)
    goldCoinDisplay:SetPoint("RIGHT", goldCard, "RIGHT", -4, 0)

    local content = BM:CreatePanel(f)
    content:SetPoint("TOPLEFT", 16, -166)
    content:SetPoint("BOTTOMRIGHT", -16, 82)
    content.themePalette = "panel"
    BM:ApplyThemeToPanel(content)

    local contentInset = CreateFrame("Frame", nil, content, "BackdropTemplate")
    contentInset:SetPoint("TOPLEFT", 10, -10)
    contentInset:SetPoint("BOTTOMRIGHT", -10, 10)
    contentInset:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Buttons/WHITE8X8",
        edgeSize = 1,
    })
    contentInset:SetBackdropColor(unpack(BM.Theme.bg))
    contentInset:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))

    local contentArt = contentInset:CreateTexture(nil, "BACKGROUND")
    contentArt:SetAllPoints()
    contentArt:SetAlpha(0)

    local footer = BM:CreatePanel(f)
    footer:SetPoint("BOTTOMLEFT", 16, 16)
    footer:SetPoint("BOTTOMRIGHT", -16, 16)
    footer:SetHeight(74)
    footer.themePalette = "footer"
    BM:ApplyThemeToPanel(footer)

    local status = f:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    status:SetPoint("LEFT", footer, "LEFT", 14, 0)
    status:SetText("")
    status:SetTextColor(unpack(BM.Theme.mutetext))

    local debug = f:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    debug:SetPoint("RIGHT", footer, "RIGHT", -14, 0)
    debug:SetText("")

    local mouseDebug = f:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    mouseDebug:SetPoint("RIGHT", debug, "LEFT", -20, 0)
    mouseDebug:SetWidth(520)
    mouseDebug:SetJustifyH("RIGHT")
    mouseDebug:SetText("")

    local scrollFrame = CreateFrame("ScrollFrame", "BetterMailboxInboxScrollFrame", contentInset, "UIPanelScrollFrameTemplate")
    scrollFrame:SetPoint("TOPLEFT", 14, -44)
    scrollFrame:SetPoint("BOTTOMRIGHT", -30, 14)

    local scrollChild = CreateFrame("Frame", nil, scrollFrame)
    scrollChild:SetSize(1, 1)
    scrollFrame:SetScrollChild(scrollChild)

    local inboxPanel = CreateFrame("Frame", nil, contentInset)
    inboxPanel:SetAllPoints(contentInset)

    local sendPanel = CreateFrame("Frame", nil, contentInset)
    sendPanel:SetAllPoints(contentInset)
    sendPanel:Hide()

    local optionsPanel = CreateFrame("Frame", nil, contentInset)
    optionsPanel:SetAllPoints(contentInset)
    optionsPanel:Hide()

    BM.ContentFrame = content
    BM.InboxPanel = inboxPanel
    BM.SendPanel = sendPanel
    BM.OptionsPanel = optionsPanel
    BM.ScrollFrame = scrollFrame
    BM.ScrollChild = scrollChild
    BM.StatusText = status
    BM.DebugText = debug
    BM.MouseDebugText = mouseDebug
    BM.MetricPanel = metrics
    BM.MetricInboxCount = inboxCountValue
    BM.MetricLootCount = lootValue
    BM.MetricGoldValue = goldValue
    BM.MetricGoldCoinDisplay = goldCoinDisplay
    BM.TabButtons = { inboxTab, sendTab }
    BM.BrandLogo = logo
    BM.TitleText = title
    BM.SubtitleText = subtitle
    BM.OptionsButton = optionsButton
    BM.CloseButton = close
    BM.InboxTabButton = inboxTab
    BM.SendTabButton = sendTab
    BM.InboxCountLabel = inboxCountLabel
    BM.LootLabel = lootLabel
    BM.GoldLabel = goldLabel
    BM.MainFrameGlow = outerGlow
    BM.WindowArt = windowArt
    BM.FrameOrnamentTop = frameOrnamentTop
    BM.FrameOrnamentBottom = frameOrnamentBottom
    BM.BrandLine = brandLine
    BM.HeaderGlow = headerGlow
    BM.HeaderRuneLeft = headerRuneLeft
    BM.HeaderRuneRight = headerRuneRight
    BM.HeaderKicker = kicker
    BM.HeaderMeta = heroMeta
    BM.LogoGlow = logoGlow
    BM.HeaderFrame = header
    BM.HeaderArt = headerArt
    BM.NavShell = navShell
    BM.MetricInboxCard = inboxCard
    BM.MetricLootCard = lootCard
    BM.MetricGoldCard = goldCard
    BM.ContentInset = contentInset
    BM.ContentArt = contentArt
    BM.FooterPanel = footer
    BM.MainFrame = f
end

local function SetPanelVisualAlpha(panel, alpha)
    if not panel then return end
    local backdropAlpha = alpha or 1
    local color = panel.themePalette and BM.Theme[panel.themePalette] or BM.Theme.panel
    if panel.SetBackdropColor then
        panel:SetBackdropColor(color[1], color[2], color[3], color[4] * backdropAlpha)
        panel:SetBackdropBorderColor(BM.Theme.border[1], BM.Theme.border[2], BM.Theme.border[3], backdropAlpha)
    end
    if panel.shadow then panel.shadow:SetAlpha(backdropAlpha) end
    if panel.accent then panel.accent:SetAlpha(backdropAlpha) end
end

function BM:ApplyPremiumWindowLayout()
    if not BM.MainFrame then return end

    BM.MainFrame:SetSize(1180, 820)
    BM.MainFrame:SetBackdropColor(unpack(BM.Theme.bg))
    BM.MainFrame:SetBackdropBorderColor(unpack(BM.Theme.border))
    if BM.MainFrameGlow then BM.MainFrameGlow:SetAlpha(0.24) end
    if BM.WindowArt then
        BM.WindowArt:SetTexture(nil)
        BM.WindowArt:SetAlpha(0)
        BM.WindowArt:Hide()
    end

    for _, panel in ipairs({ BM.HeaderFrame, BM.NavShell, BM.ContentFrame, BM.FooterPanel }) do
        SetPanelVisualAlpha(panel, 1)
    end

    if BM.ContentInset then
        BM.ContentInset:SetBackdropColor(0.02, 0.024, 0.032, 0.99)
        BM.ContentInset:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))
    end

    if BM.FrameOrnamentTop then BM.FrameOrnamentTop:SetAlpha(0) end
    if BM.FrameOrnamentBottom then BM.FrameOrnamentBottom:SetAlpha(0) end
    if BM.HeaderGlow then BM.HeaderGlow:SetAlpha(0) end
    if BM.HeaderRuneLeft then BM.HeaderRuneLeft:SetAlpha(0) end
    if BM.HeaderRuneRight then BM.HeaderRuneRight:SetAlpha(0) end
    if BM.HeaderArt then BM.HeaderArt:Hide() end
    if BM.BrandLine then BM.BrandLine:SetAlpha(0.65) end
    if BM.BrandLogo then BM.BrandLogo:Show() end
    if BM.LogoGlow then BM.LogoGlow:SetAlpha(0) end
    if BM.TitleText then
        BM.TitleText:Show()
    end
    if BM.SubtitleText then
        BM.SubtitleText:Show()
    end
    if BM.HeaderKicker then
        BM.HeaderKicker:Hide()
    end
    if BM.HeaderMeta then
        BM.HeaderMeta:Hide()
    end

    if BM.HeaderFrame then
        BM.HeaderFrame:ClearAllPoints()
        BM.HeaderFrame:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 16, -16)
        BM.HeaderFrame:SetPoint("TOPRIGHT", BM.MainFrame, "TOPRIGHT", -16, -16)
        BM.HeaderFrame:SetHeight(118)
        BM.HeaderFrame.themePalette = "hero"
        BM:ApplyThemeToPanel(BM.HeaderFrame)
        BM.HeaderFrame:SetBackdropColor(0, 0, 0, 0)
        BM.HeaderFrame:SetBackdropBorderColor(0, 0, 0, 0)
        if BM.HeaderFrame.shadow then BM.HeaderFrame.shadow:SetAlpha(0) end
        if BM.HeaderFrame.accent then BM.HeaderFrame.accent:SetAlpha(0) end
    end

    if BM.OptionsButton then
        BM.OptionsButton:Show()
        BM.OptionsButton:ClearAllPoints()
        BM.OptionsButton:SetPoint("TOPRIGHT", BM.MainFrame, "TOPRIGHT", -30, -6)
        BM.OptionsButton:SetSize(24, 20)
        if BM.OptionsButton.icon then
            BM.OptionsButton.icon:SetDesaturated(true)
            BM.OptionsButton.icon:SetVertexColor(1, 1, 1, 1)
            BM.OptionsButton.icon:SetAlpha(0.95)
        end
        if BM.OptionsButton.label then BM.OptionsButton.label:SetText("") end
    end

    if BM.CloseButton then
        BM.CloseButton:ClearAllPoints()
        BM.CloseButton:SetPoint("TOPRIGHT", BM.MainFrame, "TOPRIGHT", -6, -6)
        BM.CloseButton:SetSize(24, 20)
        if BM.CloseButton.label then BM.CloseButton.label:SetText("X") end
    end

    if BM.NavShell then
        BM.NavShell:ClearAllPoints()
        BM.NavShell:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 26, -10)
        BM.NavShell:SetPoint("TOPRIGHT", BM.MainFrame, "TOPRIGHT", -86, -10)
        BM.NavShell:SetHeight(104)
        BM.NavShell.themePalette = "panelAlt"
        BM:ApplyThemeToPanel(BM.NavShell)
        BM.NavShell:SetBackdropColor(0, 0, 0, 0)
        BM.NavShell:SetBackdropBorderColor(0, 0, 0, 0)
        if BM.NavShell.shadow then BM.NavShell.shadow:SetAlpha(0) end
        if BM.NavShell.accent then BM.NavShell.accent:SetAlpha(0) end
    end
    if BM.BrandLogo then
        BM.BrandLogo:ClearAllPoints()
        BM.BrandLogo:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 28, -18)
        BM.BrandLogo:SetSize(92, 92)
        BM.BrandLogo:SetTexture(BM.NavLogoTexture)
        BM.BrandLogo:SetTexCoord(0, 1, 0, 1)
        BM.BrandLogo:SetAlpha(1)
    end
    if BM.TitleText then
        BM.TitleText:ClearAllPoints()
        if BM.BrandLogo then
            BM.TitleText:SetPoint("TOPLEFT", BM.BrandLogo, "TOPRIGHT", 18, 8)
        else
            BM.TitleText:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 118, -18)
        end
        BM.TitleText:SetText("BetterMailbox")
        BM.TitleText:SetTextColor(0.96, 0.98, 1, 1)
        BM.TitleText:SetScale(1.2)
        BM.TitleText:SetJustifyH("LEFT")
    end
    if BM.SubtitleText then
        BM.SubtitleText:ClearAllPoints()
        BM.SubtitleText:SetPoint("TOPLEFT", BM.TitleText, "BOTTOMLEFT", 0, -4)
        BM.SubtitleText:SetText("Premium-Postfach für schnelleres Looten und Senden")
        BM.SubtitleText:SetTextColor(unpack(BM.Theme.mutetext))
        BM.SubtitleText:SetText(BM:L("subtitle"))
        BM.SubtitleText:SetJustifyH("LEFT")
    end
    if BM.BrandLine then
        BM.BrandLine:ClearAllPoints()
        BM.BrandLine:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 28, -106)
        BM.BrandLine:SetPoint("TOPRIGHT", BM.MainFrame, "TOPRIGHT", -86, -106)
        BM.BrandLine:SetHeight(1)
        BM.BrandLine:SetAlpha(0.9)
    end
    if BM.InboxTabButton then
        BM.InboxTabButton:ClearAllPoints()
        BM.InboxTabButton:SetPoint("TOPLEFT", BM.MainFrame, "TOPLEFT", 28, -120)
        BM.InboxTabButton:SetSize(140, 28)
        if BM.InboxTabButton.label then BM.InboxTabButton.label:SetText(BM:L("inbox")) end
    end
    if BM.SendTabButton then
        BM.SendTabButton:ClearAllPoints()
        BM.SendTabButton:SetPoint("LEFT", BM.InboxTabButton, "RIGHT", 12, 0)
        BM.SendTabButton:SetSize(140, 28)
        if BM.SendTabButton.label then BM.SendTabButton.label:SetText(BM:L("send")) end
    end

    if BM.MetricPanel then
        BM.MetricPanel:Show()
        BM.MetricPanel:ClearAllPoints()
        BM.MetricPanel:SetPoint("TOPLEFT", BM.FooterPanel, "TOPLEFT", 12, -8)
        BM.MetricPanel:SetPoint("TOPRIGHT", BM.FooterPanel, "TOPRIGHT", -28, -8)
        BM.MetricPanel:SetHeight(24)
        BM.MetricPanel.themePalette = "footer"
        BM:ApplyThemeToPanel(BM.MetricPanel)
    end

    local layout = BM.InboxLayoutMetrics or {}
    local metricCards = { BM.MetricInboxCard, BM.MetricLootCard, BM.MetricGoldCard }
    local metricWidths = { 120, 110, math.max(BM.CoinColumn.boxWidth, layout.goldBoxWidth or BM.CoinColumn.boxWidth) }
    local metricOffsets = { 12, 210, 0 }
    for index, card in ipairs(metricCards) do
        if card then
            card:Show()
            card:ClearAllPoints()
            card:SetSize(metricWidths[index], 16)
            card:SetBackdropColor(0, 0, 0, 0)
            card:SetBackdropBorderColor(0, 0, 0, 0)
            if index == 3 then
                card:SetPoint("LEFT", BM.MetricPanel, "LEFT", layout.goldLeftX or 0, 0)
            else
                card:SetPoint("LEFT", BM.MetricPanel, "LEFT", metricOffsets[index], 0)
            end
            if card.Label then
                card.Label:ClearAllPoints()
                if index == 3 then
                    card.Label:SetPoint("RIGHT", card, "LEFT", -12, 0)
                    card.Label:SetJustifyH("RIGHT")
                else
                    card.Label:SetPoint("LEFT", card, "LEFT", 0, 0)
                    card.Label:SetJustifyH("LEFT")
                end
                card.Label:SetWidth(index == 3 and 190 or 68)
                card.Label:SetWordWrap(false)
            end
            if card.Value then
                card.Value:ClearAllPoints()
                if index == 3 then
                    card.Value:SetPoint("LEFT", card, "LEFT", 0, 0)
                    card.Value:SetJustifyH("LEFT")
                else
                    card.Value:SetPoint("LEFT", card.Label, "RIGHT", 8, 0)
                    card.Value:SetJustifyH("LEFT")
                end
                card.Value:SetWidth(index == 3 and (layout.goldBoxWidth or 220) or 40)
                card.Value:SetWordWrap(false)
            end
        end
    end

    if BM.MetricGoldCoinDisplay then
        BM.MetricGoldCoinDisplay:ClearAllPoints()
        BM.MetricGoldCoinDisplay:SetPoint("CENTER", BM.MetricGoldCard, "CENTER", 0, 0)
        BM.MetricGoldCoinDisplay:SetWidth(layout.coinDisplayWidth or BM.CoinColumn.displayWidth)
    end

    if BM.RefreshMetricLayout then
        BM:RefreshMetricLayout()
    end

    if BM.ContentFrame then
        BM.ContentFrame:ClearAllPoints()
        BM.ContentFrame:SetPoint("TOPLEFT", BM.HeaderFrame, "BOTTOMLEFT", 0, -10)
        BM.ContentFrame:SetPoint("BOTTOMRIGHT", BM.MainFrame, "BOTTOMRIGHT", -16, 108)
        BM.ContentFrame.themePalette = "panel"
        BM:ApplyThemeToPanel(BM.ContentFrame)
    end
    if BM.ContentInset then
        BM.ContentInset:ClearAllPoints()
        BM.ContentInset:SetPoint("TOPLEFT", BM.ContentFrame, "TOPLEFT", 10, -10)
        BM.ContentInset:SetPoint("BOTTOMRIGHT", BM.ContentFrame, "BOTTOMRIGHT", -10, 10)
        BM.ContentInset:SetBackdropColor(0.018, 0.022, 0.03, 0.992)
        BM.ContentInset:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))
    end

    if BM.ScrollFrame then
        BM.ScrollFrame:ClearAllPoints()
        BM.ScrollFrame:SetPoint("TOPLEFT", BM.InboxPanel, "TOPLEFT", 12, -50)
        BM.ScrollFrame:SetPoint("BOTTOMRIGHT", BM.InboxPanel, "BOTTOMRIGHT", -30, 12)
    end

    if BM.FooterPanel then
        BM.FooterPanel:ClearAllPoints()
        BM.FooterPanel:SetPoint("BOTTOMLEFT", BM.MainFrame, "BOTTOMLEFT", 16, 16)
        BM.FooterPanel:SetPoint("BOTTOMRIGHT", BM.MainFrame, "BOTTOMRIGHT", -16, 16)
        BM.FooterPanel:SetHeight(84)
        BM.FooterPanel.themePalette = "footer"
        BM:ApplyThemeToPanel(BM.FooterPanel)
    end

    if BM.ActionButtonAnchor then
        BM.ActionButtonAnchor:ClearAllPoints()
        BM.ActionButtonAnchor:SetPoint("BOTTOM", BM.FooterPanel, "BOTTOM", 0, 10)
        BM.ActionButtonAnchor:SetSize(650, 28)
    end

    local orderedButtons = {
        BM.RefreshButton,
        BM.TakeAllButton,
        BM.TakeGoldButton,
        BM.TakeSelectedButton,
    }
    local previousButton
    for _, button in ipairs(orderedButtons) do
        if button then
            button:ClearAllPoints()
            button:SetSize(146, 28)
            if previousButton then
                button:SetPoint("RIGHT", previousButton, "LEFT", -12, 0)
            else
                button:SetPoint("RIGHT", BM.ActionButtonAnchor, "RIGHT", 0, 0)
            end
            previousButton = button
        end
    end

    if BM.StatusText then
        BM.StatusText:SetText("")
        BM.StatusText:Hide()
        BM.StatusText:ClearAllPoints()
        BM.StatusText:SetPoint("LEFT", BM.FooterPanel, "LEFT", 14, 0)
        BM.StatusText:SetWidth(240)
        BM.StatusText:SetJustifyH("LEFT")
        BM.StatusText:SetTextColor(unpack(BM.Theme.mutetext))
    end
    if BM.DebugText then
        BM.DebugText:SetText("")
        BM.DebugText:Hide()
    end
    if BM.MouseDebugText then
        BM.MouseDebugText:SetText("")
        BM.MouseDebugText:Hide()
    end
end

function BM:ApplyCurrentSkin()
    BM:ApplySkinTheme()
    if BM.MainFrameGlow then BM.MainFrameGlow:SetVertexColor(unpack(BM.Theme.accentGlow)) end
    if BM.FrameOrnamentTop then
        BM.FrameOrnamentTop:SetVertexColor(unpack(BM.Theme.ornament))
        BM.FrameOrnamentTop:SetAlpha(0)
    end
    if BM.FrameOrnamentBottom then
        BM.FrameOrnamentBottom:SetVertexColor(unpack(BM.Theme.ornamentSoft))
        BM.FrameOrnamentBottom:SetAlpha(0)
    end
    if BM.BrandLine then BM.BrandLine:SetVertexColor(unpack(BM.Theme.headerLine)) end
    if BM.HeaderGlow then BM.HeaderGlow:SetVertexColor(unpack(BM.Theme.titleGlow)) end
    if BM.HeaderRuneLeft then BM.HeaderRuneLeft:SetVertexColor(unpack(BM.Theme.accent)) end
    if BM.HeaderRuneRight then BM.HeaderRuneRight:SetVertexColor(unpack(BM.Theme.accent)) end
    if BM.LogoGlow then BM.LogoGlow:SetVertexColor(unpack(BM.Theme.titleGlow)) end
    if BM.TitleText then BM.TitleText:SetTextColor(1, 1, 1, 1) end
    if BM.HeaderKicker then BM.HeaderKicker:SetTextColor(unpack(BM.Theme.accent)) end
    if BM.HeaderMeta then BM.HeaderMeta:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.SubtitleText then BM.SubtitleText:SetTextColor(unpack(BM.Theme.text)) end
    if BM.StatusText then BM.StatusText:SetTextColor(unpack(BM.Theme.text)) end
    if BM.InboxCountLabel then BM.InboxCountLabel:SetTextColor(unpack(BM.Theme.text)) end
    if BM.LootLabel then BM.LootLabel:SetTextColor(unpack(BM.Theme.text)) end
    if BM.GoldLabel then BM.GoldLabel:SetTextColor(unpack(BM.Theme.text)) end
    if BM.InboxHeaderBar then
        BM.InboxHeaderBar:SetBackdropColor(BM.Theme.accent[1] * 0.14, BM.Theme.accent[2] * 0.14, BM.Theme.accent[3] * 0.14, 0.98)
        BM.InboxHeaderBar:SetBackdropBorderColor(unpack(BM.Theme.border))
    end
    if BM.HeaderTexts then
        for _, text in ipairs(BM.HeaderTexts) do
            text:SetTextColor(unpack(BM.Theme.text))
        end
    end
    if BM.MetricInboxCount then BM.MetricInboxCount:SetTextColor(unpack(BM.Theme.text)) end
    if BM.MetricLootCount then BM.MetricLootCount:SetTextColor(unpack(BM.Theme.text)) end
    if BM.MetricGoldValue then BM.MetricGoldValue:SetTextColor(unpack(BM.Theme.text)) end

    for _, panel in ipairs(BM.ThemedPanels or {}) do
        BM:ApplyThemeToPanel(panel)
    end
    for _, input in ipairs(BM.ThemedInputs or {}) do
        input:SetBackdropColor(unpack(BM.Theme.input))
        input:SetBackdropBorderColor(unpack(BM.Theme.inputBorder))
    end
    if BM.ContentInset then
        BM.ContentInset:SetBackdropColor(0.018, 0.022, 0.03, 0.992)
        BM.ContentInset:SetBackdropBorderColor(unpack(BM.Theme.borderSoft))
    end
    for _, card in ipairs({ BM.MetricInboxCard, BM.MetricLootCard, BM.MetricGoldCard }) do
        if card then
            card:SetBackdropColor(0, 0, 0, 0)
            card:SetBackdropBorderColor(0, 0, 0, 0)
        end
    end
    if BM.HeaderArt then
        BM.HeaderArt:SetTexture(nil)
        BM.HeaderArt:Hide()
    end
    if BM.ContentArt then
        BM.ContentArt:SetTexture(nil)
        BM.ContentArt:Hide()
    end
    for _, button in ipairs(BM.ThemedButtons or {}) do
        BM:ApplyThemeToButton(button)
    end
    for _, row in ipairs(BM.Rows or {}) do
        row.baseColor = { 0.022, 0.026, 0.032, 0.98 }
        row.baseBorderColor = { BM.Theme.border[1] * 0.9, BM.Theme.border[2] * 0.9, BM.Theme.border[3] * 0.9, 0.95 }
        row.hoverColor = { BM.Theme.accent[1] * 0.22, BM.Theme.accent[2] * 0.22, BM.Theme.accent[3] * 0.22, 0.99 }
        row.selectedColor = { BM.Theme.accent[1] * 0.32, BM.Theme.accent[2] * 0.32, BM.Theme.accent[3] * 0.32, 0.995 }
        row.selectedBorderColor = { BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 1 }
        row.baseAccentColor = { BM.Theme.accent[1] * 0.45, BM.Theme.accent[2] * 0.45, BM.Theme.accent[3] * 0.45, 0.7 }
        row.selectedAccentColor = { BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 1 }
        if row.leftAccent then row.leftAccent:SetAlpha(1) end
        if row.topShine then row.topShine:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.28) end
        if row.selectionGlow then row.selectionGlow:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.24) end
        if row.badge then row.badge:Hide() end
        if row.item then row.item:SetTextColor(unpack(BM.Theme.text)) end
        if row.meta then row.meta:SetTextColor(unpack(BM.Theme.mutetext)) end
        if row.sender then row.sender:SetTextColor(unpack(BM.Theme.text)) end
        if row.expire then row.expire:SetTextColor(unpack(BM.Theme.text)) end
        if row.goldBox then
            row.goldBox:SetBackdropColor(BM.Theme.accent[1] * 0.1, BM.Theme.accent[2] * 0.1, BM.Theme.accent[3] * 0.1, 0.94)
            row.goldBox:SetBackdropBorderColor(BM.Theme.border[1], BM.Theme.border[2], BM.Theme.border[3], 0.95)
        end
        if row.UpdateVisualState and row:IsShown() then
            row:UpdateVisualState(false)
        end
    end

    BM:ApplyPremiumWindowLayout()
end

function BM:UpdateTexts()
    if BM.TitleText then BM.TitleText:SetText("BetterMailbox") end
    if BM.SubtitleText then BM.SubtitleText:SetText(BM:L("subtitle")) end
    if BM.HeaderKicker then BM.HeaderKicker:SetText("") end
    if BM.OptionsButton and BM.OptionsButton.label then BM.OptionsButton.label:SetText("") end
    if BM.InboxTabButton and BM.InboxTabButton.label then BM.InboxTabButton.label:SetText(BM:L("inbox")) end
    if BM.SendTabButton and BM.SendTabButton.label then BM.SendTabButton.label:SetText(BM:L("send")) end
    if BM.InboxCountLabel then BM.InboxCountLabel:SetText(BM:L("mails")) end
    if BM.LootLabel then BM.LootLabel:SetText(BM:L("lootable")) end
    if BM.GoldLabel then BM.GoldLabel:SetText(BM:L("attached_gold")) end
    if BM.UpdateInboxTexts then BM:UpdateInboxTexts() end
    if BM.UpdateSendTexts then BM:UpdateSendTexts() end
    if BM.UpdateActionTexts then BM:UpdateActionTexts() end
    if BM.UpdateOptionsTexts then BM:UpdateOptionsTexts() end
    if BM.ApplyFontSize then BM:ApplyFontSize() end
    if BM.ApplyCurrentSkin then BM:ApplyCurrentSkin() end
    if BM.RefreshMetricLayout then BM:RefreshMetricLayout() end
end

function BM:ShowUI()
    if not BM.MainFrame then
        BM:CreateMainFrame()
        BM:CreateInbox()
        BM:CreateSendUI()
        BM:CreateTakeAll()
        BM:CreateOptionsPanel()
    end

    BM.uiReady = BM.MainFrame and BM.ScrollFrame and BM.ScrollChild and BM.InboxPanel and true or false
    if BM.ApplyScale then BM:ApplyScale() end
    BM.MainFrame:Show()
    BM.MainFrame:Raise()
    if BM.EmbedSendAttachmentSlots then BM:EmbedSendAttachmentSlots() end
    BM:UpdateTexts()
    BM:SelectTab(BM.currentTab)
end

function BM:HideUI()
    if BM.MainFrame then
        BM.MainFrame:Hide()
    end
end
