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,
}

BM.Skins = {
    blackgrey = { name = "Black/Grey", accent = { 0.62, 0.66, 0.72, 1 }, accentSoft = { 0.42, 0.46, 0.52, 1 }, border = { 0.14, 0.14, 0.15, 1 }, borderSoft = { 0.1, 0.1, 0.11, 1 }, titleAccent = { 1, 1, 1, 1 }, titleGlow = { 0.18, 0.2, 0.24, 0.08 } },
    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.055, 0.045, 0.04, 0.995 },
    panel = { 0.075, 0.064, 0.056, 0.98 },
    panelAlt = { 0.09, 0.078, 0.068, 0.985 },
    content = { 0.17, 0.17, 0.17, 0.985 },
    border = { 0.22, 0.19, 0.14, 1 },
    borderSoft = { 0.15, 0.13, 0.1, 1 },
    accent = { 0.98, 0.84, 0.16, 1 },
    accentSoft = { 0.76, 0.63, 0.18, 1 },
    accentGlow = { 0.38, 0.28, 0.08, 0.08 },
    text = { 0.95, 0.93, 0.87, 1 },
    mutetext = { 0.77, 0.73, 0.64, 1 },
    success = { 0.7, 0.9, 0.58, 1 },
    danger = { 1, 0.45, 0.38, 1 },
    headerLine = { 0.28, 0.23, 0.16, 0.95 },
    titleAccent = { 1, 0.98, 0.92, 1 },
    titleGlow = { 0.34, 0.24, 0.08, 0.08 },
    ornament = { 0.08, 0.065, 0.05, 0.18 },
    ornamentSoft = { 0.06, 0.05, 0.04, 0.2 },
    footer = { 0.065, 0.055, 0.048, 0.985 },
    metric = { 0.065, 0.055, 0.048, 0.985 },
    hero = { 0.065, 0.055, 0.048, 0.985 },
    settings = { 0.085, 0.073, 0.064, 0.97 },
    input = { 0.125, 0.125, 0.125, 0.985 },
    inputBorder = { 0.24, 0.21, 0.16, 1 },
}

function BM:GetSkin()
    BetterMailboxDB = BetterMailboxDB or {}
    local key = BetterMailboxDB.skin or "blackgrey"
    return BM.Skins[key] and key or "blackgrey"
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
    local accent = skin.accent or { 0.9, 0.9, 0.9, 1 }
    local accentSoft = skin.accentSoft or accent
    local border = skin.border or { 0.12, 0.12, 0.12, 1 }
    local borderSoft = skin.borderSoft or border

    BM.Theme.accent = { accent[1], accent[2], accent[3], 1 }
    BM.Theme.accentSoft = { accentSoft[1], accentSoft[2], accentSoft[3], 1 }
    BM.Theme.border = { border[1], border[2], border[3], 1 }
    BM.Theme.borderSoft = {
        math.max(0.05, borderSoft[1] * 0.85),
        math.max(0.05, borderSoft[2] * 0.85),
        math.max(0.05, borderSoft[3] * 0.85),
        1,
    }
    BM.Theme.titleAccent = { 1, 1, 1, 1 }
    BM.Theme.titleGlow = { accent[1], accent[2], accent[3], 0.1 }
    BM.Theme.accentGlow = { accent[1], accent[2], accent[3], 0.12 }
    BM.Theme.headerLine = { border[1], border[2], border[3], 0.95 }
    BM.Theme.inputBorder = { border[1], border[2], border[3], 1 }
    BM.Theme.text = {
        math.min(1, accent[1] * 0.78 + 0.28),
        math.min(1, accent[2] * 0.78 + 0.28),
        math.min(1, accent[3] * 0.78 + 0.28),
        1,
    }
    BM.Theme.mutetext = {
        math.min(1, accent[1] * 0.52 + 0.34),
        math.min(1, accent[2] * 0.52 + 0.34),
        math.min(1, accent[3] * 0.52 + 0.34),
        1,
    }
    BM.Theme.success = { 0.7, 0.9, 0.58, 1 }
    BM.Theme.danger = { 1, 0.45, 0.38, 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)
    button:EnableMouse(true)
    button:RegisterForClicks("LeftButtonUp")
    button:SetBackdrop({
        bgFile = "Interface/Buttons/WHITE8X8",
        edgeFile = "Interface/Buttons/WHITE8X8",
        edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 },
    })

    if not button.hoverFill then
        button.hoverFill = button:CreateTexture(nil, "OVERLAY", nil, 6)
        button.hoverFill:SetTexture("Interface/Buttons/WHITE8X8")
        button.hoverFill:SetPoint("TOPLEFT", button, "TOPLEFT", 1, -1)
        button.hoverFill:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 1)
        button.hoverFill:SetBlendMode("BLEND")
        button.hoverFill:Hide()

        button.nativeHighlight = button:CreateTexture(nil, "HIGHLIGHT", nil, 7)
        button.nativeHighlight:SetTexture("Interface/Buttons/WHITE8X8")
        button.nativeHighlight:SetPoint("TOPLEFT", button, "TOPLEFT", 1, -1)
        button.nativeHighlight:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 1)
        button.nativeHighlight:SetBlendMode("BLEND")
        button.nativeHighlight:SetVertexColor(1, 0, 0, 0.35)
        button:SetHighlightTexture(button.nativeHighlight)

        button.nativePushed = button:CreateTexture(nil, "ARTWORK", nil, 7)
        button.nativePushed:SetTexture("Interface/Buttons/WHITE8X8")
        button.nativePushed:SetPoint("TOPLEFT", button, "TOPLEFT", 1, -1)
        button.nativePushed:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 1)
        button.nativePushed:SetBlendMode("BLEND")
        button.nativePushed:SetVertexColor(1, 0, 0, 0.5)
        button:SetPushedTexture(button.nativePushed)

        button.topLine = button:CreateTexture(nil, "OVERLAY")
        button.topLine:SetTexture("Interface/Buttons/WHITE8X8")
        button.topLine:SetPoint("TOPLEFT", button, "TOPLEFT", 1, -1)
        button.topLine:SetPoint("TOPRIGHT", button, "TOPRIGHT", -1, -1)
        button.topLine:SetHeight(1)

        button.bottomLine = button:CreateTexture(nil, "OVERLAY")
        button.bottomLine:SetTexture("Interface/Buttons/WHITE8X8")
        button.bottomLine:SetPoint("BOTTOMLEFT", button, "BOTTOMLEFT", 1, 1)
        button.bottomLine:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -1, 1)
        button.bottomLine:SetHeight(1)

        button.focusRing = button:CreateTexture(nil, "OVERLAY", nil, 7)
        button.focusRing:SetTexture("Interface/Buttons/WHITE8X8")
        button.focusRing:SetPoint("TOPLEFT", button, "TOPLEFT", 0, 0)
        button.focusRing:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", 0, 0)
        button.focusRing:SetBlendMode("ADD")
        button.focusRing:Hide()

        button.label = button:CreateFontString(nil, "OVERLAY", "GameFontDisable")
        button.label:SetPoint("CENTER", 0, 0)
        button.label:SetJustifyH("CENTER")
        button.label:SetWordWrap(false)
    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 "")

    local function applyState(state)
        local baseR = (BM.Theme.content and BM.Theme.content[1]) or 0.17
        local baseG = (BM.Theme.content and BM.Theme.content[2]) or 0.17
        local baseB = (BM.Theme.content and BM.Theme.content[3]) or 0.17
        local accent = BM.Theme.accent or { 0.8, 0.8, 0.8, 1 }
        local muted = BM.Theme.mutetext or { 0.72, 0.72, 0.72, 1 }
        local bright = BM.Theme.text or { 0.92, 0.92, 0.92, 1 }
        local border = BM.Theme.borderSoft or { 0.08, 0.08, 0.08, 1 }

        button:SetBackdropColor(baseR, baseG, baseB, 0.96)
        button:SetBackdropBorderColor(border[1], border[2], border[3], 1)
        button.hoverFill:SetBlendMode("BLEND")
        button.hoverFill:Hide()
        button.focusRing:Hide()
        if button.nativeHighlight then
            button.nativeHighlight:SetVertexColor(accent[1], accent[2], accent[3], 0.38)
        end
        if button.nativePushed then
            button.nativePushed:SetVertexColor(accent[1], accent[2], accent[3], 0.56)
        end
        button.topLine:SetVertexColor(0.34, 0.34, 0.34, 0.35)
        button.bottomLine:SetVertexColor(0.08, 0.08, 0.08, 0.9)
        button.label:SetTextColor(unpack(muted))

        if button.style == "tab" and state == "active" then
            button:SetBackdropColor(
                accent[1],
                accent[2],
                accent[3],
                1
            )
            button:SetBackdropBorderColor(1, 1, 1, 1)
            button.hoverFill:SetVertexColor(1, 1, 1, 0.24)
            button.hoverFill:Show()
            button.focusRing:SetVertexColor(1, 1, 1, 0.32)
            button.focusRing:Show()
            button.label:SetTextColor(1, 1, 1)
            return
        end

        if state == "hover" then
            button:SetBackdropColor(
                accent[1],
                accent[2],
                accent[3],
                0.82
            )
            button:SetBackdropBorderColor(1, 1, 1, 1)
            button.hoverFill:SetVertexColor(1, 1, 1, 0.1)
            button.hoverFill:Show()
            button.focusRing:SetVertexColor(1, 1, 1, 0.16)
            button.focusRing:Show()
            button.label:SetTextColor(1, 1, 1)
        elseif state == "pressed" then
            button:SetBackdropColor(
                accent[1],
                accent[2],
                accent[3],
                1
            )
            button:SetBackdropBorderColor(1, 1, 1, 1)
            button.hoverFill:SetVertexColor(0, 0, 0, 0.12)
            button.hoverFill:Show()
            button.focusRing:SetVertexColor(1, 1, 1, 0.24)
            button.focusRing:Show()
            button.label:SetTextColor(1, 1, 1)
        else
            if button.style == "tab" then
                button.label:SetTextColor(unpack(bright))
            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
            if self.style == "tab" and self.tabKey == BM.currentTab then
                self:ApplyVisualState("active")
            else
                self:ApplyVisualState("hover")
            end
        end
    end)
    button:SetScript("OnEnter", function(self)
        if self.ApplyVisualState then
            if self.style == "tab" and self.tabKey == BM.currentTab then
                self:ApplyVisualState("active")
            else
                self:ApplyVisualState("hover")
            end
        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, "BackdropTemplate")
    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)
        if self.tabKey == "send" and BM.OpenInventoryBags then
            if BM.SetStatus then
                BM:SetStatus("BetterMailbox: Senden geklickt, oeffne Taschen...", 0.13, 0.72, 1)
            end
            BM:OpenInventoryBags()
        end
        C_Timer.After(0, function()
            if self and self.ApplyVisualState and BM.currentTab == self.tabKey then
                self:ApplyVisualState("active")
            end
        end)
    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 goldRightInset = 32
    local goldLeftX = math.max(0, (BM.MetricPanel:GetWidth() or 0) - goldBoxWidth - goldRightInset)

    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"

    local showingOpenMail = BM.currentTab == "inbox" and BM.openMailIndex and BM.OpenMailPanel
    local showingInboxList = BM.currentTab == "inbox" and not showingOpenMail

    if BM.InboxPanel then BM.InboxPanel:SetShown(showingInboxList) end
    if BM.OpenMailPanel then BM.OpenMailPanel:SetShown(showingOpenMail and true or false) 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(showingInboxList) end
    if BM.ActionBar then BM.ActionBar:SetShown(showingInboxList) end

    BM:UpdateTabButtons()
    C_Timer.After(0, function()
        if BM.UpdateTabButtons then
            BM:UpdateTabButtons()
        end
    end)

    if BM.currentTab == "inbox" then
        if showingOpenMail then
            if BM.RefreshOpenMail then
                BM:RefreshOpenMail()
            end
        elseif 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))
    title:SetShadowOffset(2, -2)
    title:SetShadowColor(BM.Theme.titleGlow[1], BM.Theme.titleGlow[2], BM.Theme.titleGlow[3], 0.9)

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

    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("")

    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.NavBar = navBar
    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(1260, 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(0.12, 0.12, 0.12, 1)
    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.HeaderFrame then
        BM.HeaderFrame:SetHeight(118)
    end
    if BM.NavShell then
        BM.NavShell:ClearAllPoints()
        BM.NavShell:SetPoint("TOPLEFT", BM.HeaderFrame, "BOTTOMLEFT", 18, -10)
        BM.NavShell:SetSize(320, 34)
        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.NavBar then
        BM.NavBar:ClearAllPoints()
        BM.NavBar:SetPoint("TOPLEFT", BM.NavShell, "TOPLEFT", 0, 0)
        BM.NavBar:SetPoint("BOTTOMRIGHT", BM.NavShell, "BOTTOMRIGHT", 0, 0)
    end
    if BM.BrandLogo then
        BM.BrandLogo:ClearAllPoints()
        BM.BrandLogo:SetPoint("TOPLEFT", BM.HeaderFrame, "TOPLEFT", 18, 8)
        BM.BrandLogo:SetSize(108, 108)
        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("LEFT", BM.BrandLogo, "RIGHT", 18, 14)
        else
            BM.TitleText:SetPoint("TOPLEFT", BM.HeaderFrame, "TOPLEFT", 118, -12)
        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, -8)
        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("BOTTOMLEFT", BM.HeaderFrame, "BOTTOMLEFT", 18, 16)
        BM.BrandLine:SetPoint("BOTTOMRIGHT", BM.HeaderFrame, "BOTTOMRIGHT", -86, 16)
        BM.BrandLine:SetHeight(1)
        BM.BrandLine:SetAlpha(0.9)
    end
    if BM.InboxTabButton then
        BM.InboxTabButton:ClearAllPoints()
        BM.InboxTabButton:SetPoint("LEFT", BM.NavBar, "LEFT", 0, 0)
        BM.InboxTabButton:SetSize(154, 26)
        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(154, 26)
        if BM.SendTabButton.label then BM.SendTabButton.label:SetText(BM:L("send")) end
    end
    if BM.ContentFrame then
        BM.ContentFrame:ClearAllPoints()
        BM.ContentFrame:SetPoint("TOPLEFT", BM.NavShell, "BOTTOMLEFT", -2, -10)
        BM.ContentFrame:SetPoint("BOTTOMRIGHT", BM.FooterPanel, "TOPRIGHT", 0, 12)
    end

    if BM.MetricPanel then
        BM.MetricPanel:SetShown(BM.currentTab == "inbox" and not BM.openMailIndex)
        BM.MetricPanel:ClearAllPoints()
        BM.MetricPanel:SetPoint("TOPLEFT", BM.FooterPanel, "TOPLEFT", 24, -8)
        BM.MetricPanel:SetPoint("TOPRIGHT", BM.FooterPanel, "TOPRIGHT", -30, -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 = { 150, 140, math.max(260, layout.goldBoxWidth or BM.CoinColumn.boxWidth) }
    local metricOffsets = { 12, 250, 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 220 or 110)
                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 math.max(220, layout.goldBoxWidth or 220) or 56)
                card.Value:SetWordWrap(false)
            end
        end
    end

    if BM.RefreshMetricLayout then
        BM:RefreshMetricLayout()
    end

    if BM.ContentFrame then
        BM.ContentFrame:ClearAllPoints()
        BM.ContentFrame:SetPoint("TOPLEFT", BM.NavShell, "BOTTOMLEFT", -2, -8)
        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(unpack(BM.Theme.content))
        BM.ContentInset:SetBackdropBorderColor(0.12, 0.12, 0.12, 1)
    end

    if BM.ScrollFrame then
        BM.ScrollFrame:ClearAllPoints()
        BM.ScrollFrame:SetPoint("TOPLEFT", BM.InboxPanel, "TOPLEFT", 12, -56)
        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(960, 32)
    end

        local orderedButtons = {
        BM.RefreshButton,
        BM.DeleteButton,
        BM.TakeAllButton,
        BM.TakeGoldButton,
        BM.TakeSelectedButton,
    }
    local previousButton
    for _, button in ipairs(orderedButtons) do
        if button then
            button:ClearAllPoints()
            button:SetSize(180, 32)
            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(320)
        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)
        BM.TitleText:SetShadowOffset(2, -2)
        BM.TitleText:SetShadowColor(BM.Theme.titleGlow[1], BM.Theme.titleGlow[2], BM.Theme.titleGlow[3], 0.9)
    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.OpenMailTitle then BM.OpenMailTitle:SetTextColor(unpack(BM.Theme.text)) end
    if BM.OpenMailSenderLabel then BM.OpenMailSenderLabel:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.OpenMailSenderValue then BM.OpenMailSenderValue:SetTextColor(unpack(BM.Theme.text)) end
    if BM.OpenMailExpiresLabel then BM.OpenMailExpiresLabel:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.OpenMailExpiresValue then BM.OpenMailExpiresValue:SetTextColor(unpack(BM.Theme.text)) end
    if BM.OpenMailBodyLabel then BM.OpenMailBodyLabel:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.OpenMailBodyText then BM.OpenMailBodyText:SetTextColor(unpack(BM.Theme.text)) end
    if BM.OpenMailAttachmentsLabel then BM.OpenMailAttachmentsLabel:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.OpenMailNoAttachments then BM.OpenMailNoAttachments:SetTextColor(unpack(BM.Theme.mutetext)) end
    if BM.OpenMailAttachedGoldLabel then BM.OpenMailAttachedGoldLabel:SetTextColor(unpack(BM.Theme.mutetext)) 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(0.12, 0.12, 0.12, 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(unpack(BM.Theme.content))
        BM.ContentInset:SetBackdropBorderColor(0.12, 0.12, 0.12, 1)
    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.145, 0.145, 0.145, 0.985 }
        row.baseBorderColor = { 0.11, 0.11, 0.11, 1 }
        row.hoverColor = {
            math.min(0.28, BM.Theme.accent[1] * 0.12 + 0.12),
            math.min(0.28, BM.Theme.accent[2] * 0.12 + 0.12),
            math.min(0.28, BM.Theme.accent[3] * 0.12 + 0.12),
            0.995,
        }
        row.selectedColor = {
            math.min(0.42, BM.Theme.accent[1] * 0.22 + 0.14),
            math.min(0.42, BM.Theme.accent[2] * 0.22 + 0.14),
            math.min(0.42, BM.Theme.accent[3] * 0.22 + 0.14),
            0.995,
        }
        row.selectedBorderColor = { BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 1 }
        row.baseAccentColor = { BM.Theme.accent[1] * 0.35, BM.Theme.accent[2] * 0.35, BM.Theme.accent[3] * 0.35, 0.55 }
        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] * 0.45, BM.Theme.accent[2] * 0.45, BM.Theme.accent[3] * 0.45, 0.24) end
        if row.selectionGlow then row.selectionGlow:SetVertexColor(BM.Theme.accent[1], BM.Theme.accent[2], BM.Theme.accent[3], 0.18) 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.deleteBox and row.UpdateDeleteCheckbox then
            row:UpdateDeleteCheckbox()
        end
        if row.goldBox then
            row.goldBox:SetBackdropColor(0.1, 0.1, 0.1, 0.96)
            row.goldBox:SetBackdropBorderColor(0.14, 0.14, 0.14, 1)
        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.UpdateOpenMailTexts then BM:UpdateOpenMailTexts() 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.CloseInventoryBagsOpenedForSend then
        BM:CloseInventoryBagsOpenedForSend()
    end
    if BM.MainFrame then
        BM.MainFrame:Hide()
    end
end




























