import AppKit
import CodexBarCore
import Observation
import QuartzCore
import SwiftUI

// MARK: - NSMenu construction

extension StatusItemController {
    static let menuCardBaseWidth: CGFloat = 310
    private static let maxOverviewProviders = SettingsStore.mergedOverviewProviderLimit
    static let overviewRowIdentifierPrefix = "overviewRow-"
    static let persistentRefreshMenuItemID = "persistentRefreshAction"
    private static let defaultMenuOpenRefreshDelay: Duration = .seconds(1.2)
    #if DEBUG
    private static var menuOpenRefreshDelayForTesting: Duration = .seconds(1.2)
    static func setMenuOpenRefreshDelayForTesting(_ delay: Duration) {
        self.menuOpenRefreshDelayForTesting = delay
    }

    static func resetMenuOpenRefreshDelayForTesting() {
        self.menuOpenRefreshDelayForTesting = self.defaultMenuOpenRefreshDelay
    }
    #endif

    private static var menuOpenRefreshDelay: Duration {
        #if DEBUG
        menuOpenRefreshDelayForTesting
        #else
        defaultMenuOpenRefreshDelay
        #endif
    }

    static let usageBreakdownChartID = "usageBreakdownChart"
    static let creditsHistoryChartID = "creditsHistoryChart"
    static let costHistoryChartID = "costHistoryChart"
    static let usageHistoryChartID = "usageHistoryChart"
    static let storageBreakdownID = "storageBreakdown"
    static let statusComponentsID = "statusComponents"

    func shortcut(for action: MenuDescriptor.MenuAction) -> (key: String, modifiers: NSEvent.ModifierFlags)? {
        switch action {
        case .refresh:
            ("r", [.command])
        case .settings:
            (",", [.command])
        case .quit:
            ("q", [.command])
        default:
            nil
        }
    }

    func makeMenu() -> NSMenu {
        guard self.shouldMergeIcons else {
            return self.makeMenu(for: nil)
        }
        return self.makeBaseMenu()
    }

    func menuNeedsUpdate(_ menu: NSMenu) {
        guard self.shouldMergeIcons, menu === self.mergedMenu else { return }
        self.refreshMenuForOpenIfNeeded(menu, provider: self.resolvedMenuProvider())
    }

    func menuWillOpen(_ menu: NSMenu) {
        if menu.supermenu == nil {
            // Records interaction and may bring an adaptive timer forward; never refreshes
            // synchronously. Root opens only: hover-opening a hosted chart submenu must not kick
            // off an agent-session rescan — the scan completion invalidates the tracked parent
            // while its submenu is open, and on the Overview tab the resulting structural parent
            // rebuild force-closes the hovered submenu. Each reopen then triggered another rescan,
            // producing an infinite open/close/rebuild flicker loop (#2652).
            self.store.noteMenuOpened()
            self.agentSessions.refreshOnMenuOpen()
        }

        let trace = self.beginMenuOperationTrace("menuWillOpen", breadcrumb: "menuWillOpen")
        defer { self.endMenuOperationTrace(trace, menu: menu, provider: self.menuProvider(for: menu)) }

        // Keep the menu drawing in the current system appearance rather than the menu bar's
        // (possibly dark) vibrant appearance. Done before any early return so submenus match too.
        StatusMenuAppearance.pin(menu)

        self.cancelDeferredMenuInteractionRefreshTask()
        self.cancelClosedMenuRebuild(menu)

        self.beginMenuTrackingSession(for: menu)

        // Track whether this is the root menu opening (no menus were open). Only the root open rebuilds
        // all content from current data, so the readiness baseline is re-anchored only here — re-anchoring
        // on a nested submenu open could mask a pending refresh for the already-open parent menu.
        let menuTrackingWasIdle = self.openMenus.isEmpty

        if self.isHostedSubviewMenu(menu) {
            if !self.hydrateHostedSubviewMenuIfNeeded(menu) {
                self.refreshHostedSubviewMenu(menu)
            }
            if self.isMenuRefreshEnabled, self.isOpenAIWebSubviewMenu(menu) {
                self.deferOpenAIDashboardRefreshUntilMenuCloses(reason: "submenu open")
            }
            if self.isMenuRefreshEnabled {
                // Intentionally skip open-menu tracking when refresh is disabled (tests).
                // If refresh is re-enabled while this menu stays open, it will not be backfilled until next open.
                self.openMenus[ObjectIdentifier(menu)] = menu
                if menuTrackingWasIdle {
                    self.resyncMenuAdjunctReadinessBaseline()
                }
            }
            // Removed redundant async refresh - single pass is sufficient after initial layout
            return
        }

        var provider: UsageProvider?
        if self.shouldMergeIcons {
            // Provider-specific by design: Codex is the persisted menu identity fallback when selection is empty.
            let resolvedProvider = self.resolvedMenuProvider()
            self.lastMenuProvider = (resolvedProvider ?? .codex).instanceID
            provider = resolvedProvider
        } else {
            if let menuProvider = self.menuProviders[ObjectIdentifier(menu)] {
                self.lastMenuProvider = menuProvider
                provider = menuProvider.firstPartyProvider
            } else if menu === self.fallbackMenu {
                self.lastMenuProvider = self.store.enabledProvidersForDisplay().first ?? .codex
                provider = nil
            } else {
                let resolved = self.store.enabledProvidersForDisplay().first ?? .codex
                self.lastMenuProvider = resolved
                provider = resolved.firstPartyProvider
            }
        }

        if self.isMenuRefreshEnabled, (provider?.instanceID ?? self.lastMenuProvider) == .codex {
            self.deferOpenAIDashboardRefreshUntilMenuCloses(reason: "parent menu open")
        }
        if self.settings.providerStorageFootprintsEnabled {
            self.store.refreshStorageFootprintsForOverview()
        }

        let menuWasFreshBeforeOpen = !self.menuNeedsRefresh(menu)
        self.refreshMenuForOpenIfNeeded(menu, provider: provider)
        self.scheduleCodexAccountMenuProjectionRevalidationIfNeeded(
            for: self.renderedProviders(for: menu))
        if self.isMenuRefreshEnabled {
            // Intentionally skip open-menu tracking when refresh is disabled (tests).
            // If refresh is re-enabled while this menu stays open, it will not be backfilled until next open.
            self.openMenus[ObjectIdentifier(menu)] = menu
            // Only re-anchor when the opened menu actually shows current data. During an in-flight provider
            // refresh `refreshMenuForOpenIfNeeded` can preserve stale content; resyncing the baseline to
            // live store data in that case would mask the refresh-completion update (#1351).
            if menuTrackingWasIdle, !self.menuNeedsRefresh(menu) {
                self.resyncMenuAdjunctReadinessBaselineForRootOpen(
                    menu,
                    provider: provider,
                    menuWasFreshBeforeOpen: menuWasFreshBeforeOpen)
            }
            self.installProviderSwitcherShortcutMonitorIfNeeded(for: menu)
            // Only schedule refresh after menu is registered as open - refreshNow is called async
            self.scheduleOpenMenuRefresh(for: menu)
        }
    }

    func menuDidClose(_ menu: NSMenu) {
        let wasHostedSubviewMenu = self.isHostedSubviewMenu(menu)
        self.forgetClosedMenu(menu)
        if wasHostedSubviewMenu {
            self.refreshOpenMenusAfterHostedSubviewClose()
        }
        if self.openMenus.isEmpty {
            self.cancelMergedSwitcherSiblingWarmup()
        }
        self.resetCompactAccountMenuExpansionStateIfIdle()
    }

    func forgetClosedMenu(_ menu: NSMenu) {
        let key = ObjectIdentifier(menu)
        let wasMergedMenu = menu === self.mergedMenu

        self.endMenuTrackingSession(for: menu)

        if key == self.providerSwitcherShortcutMenuID {
            self.removeProviderSwitcherShortcutMonitor()
        }

        self.clearMergedSwitcherContentCache(for: menu)
        let wasTracked = self.openMenus.removeValue(forKey: key) != nil
        let menuTrackingEnded = wasTracked && self.openMenus.isEmpty
        if self.openMenus.isEmpty {
            self.parentMenuRebuildPendingAfterHostedSubviewClose = false
        }
        self.cancelMenuWork(key)
        self.clearMenuHighlight(key)

        let isPersistentMenu = menu === self.mergedMenu ||
            menu === self.fallbackMenu ||
            self.providerMenus.values.contains { $0 === menu }
        if !isPersistentMenu {
            self.removeMenuTrackingState(key)
        } else if self.menuNeedsRefresh(menu) {
            self.handleClosedPersistentMenuNeedingRefresh(menu)
        }
        self.menuSession.clearParentRebuildDeferral(key)
        self.scheduleDeferredMenuInteractionRefreshIfNeeded()
        if wasMergedMenu {
            self.applyDeferredMergedIconRenderAfterTrackingIfNeeded()
        }
        if menuTrackingEnded {
            self.prepareAttachedClosedMenusIfNeeded()
        }
    }

    func menu(_ menu: NSMenu, willHighlight item: NSMenuItem?) {
        let key = ObjectIdentifier(menu)
        let previous = self.highlightedMenuItems[key]
        guard previous !== item else { return }
        let previousWasNative = self.isNativeMenuItemHighlighted(in: menu)

        if let previous {
            (previous.view as? MenuCardHighlighting)?.setHighlighted(false)
        }

        if let item,
           item.isEnabled,
           (item.view as? MenuCardHighlighting)?.allowsMenuHighlight != false
        {
            self.highlightedMenuItems[key] = item
            (item.view as? MenuCardHighlighting)?.setHighlighted(true)
        } else {
            self.highlightedMenuItems.removeValue(forKey: key)
        }

        if previousWasNative, !self.isNativeMenuItemHighlighted(in: menu) {
            self.resumeMenuRebuildDeferredForNativeHighlightIfNeeded(menu)
        }
    }

    func populateMenu(_ menu: NSMenu, provider: UsageProvider?) {
        let trace = self.beginMenuOperationTrace(
            "populateMenu",
            breadcrumb: "populateMenu:\(provider?.rawValue ?? "merged")")
        defer { self.endMenuOperationTrace(trace, menu: menu, provider: provider) }
        defer { self.refreshMenuCardHeights(in: menu) }
        // Re-warm sibling tab caches after every populate of the open merged menu so a
        // tab switch attaches pre-rendered rows; no-ops for closed or non-merged menus.
        defer { self.scheduleMergedSwitcherSiblingWarmup(for: menu) }

        let enabledProviders = self.store.enabledFirstPartyProvidersForDisplay()
        let includesOverview = self.includesOverviewTab(enabledProviders: enabledProviders)
        let switcherSelection = self.shouldMergeIcons && enabledProviders.count > 1
            ? self.resolvedSwitcherSelection(
                enabledProviders: enabledProviders,
                includesOverview: includesOverview)
            : nil
        let isOverviewSelected = switcherSelection == .overview
        let selectedProvider = if isOverviewSelected {
            self.resolvedMenuProvider(enabledProviders: enabledProviders)
        } else {
            switcherSelection?.provider ?? provider
        }
        // Provider-specific by design: Codex remains the empty merged-menu selection fallback.
        let currentProvider = selectedProvider ?? enabledProviders.first ?? .codex
        let rawCodexAccountDisplay = isOverviewSelected ? nil : self.codexAccountMenuDisplay(for: currentProvider)
        let codexAccountDisplay = isOverviewSelected
            ? nil
            : self.stableCodexAccountMenuDisplay(
                rawCodexAccountDisplay,
                menu: menu,
                provider: currentProvider)
        let tokenAccountDisplay = isOverviewSelected ? nil : self.tokenAccountMenuDisplay(for: currentProvider)
        let showAllAccounts = (tokenAccountDisplay?.showAll ?? false) || (codexAccountDisplay?.showAll ?? false)
        let openAIContext = self.openAIWebContext(
            currentProvider: currentProvider,
            showAllAccounts: showAllAccounts)
        let descriptor = self.makeMenuDescriptor(
            provider: selectedProvider,
            includeContextualActions: !isOverviewSelected)
        let menuWidth = self.menuCardWidth(
            for: enabledProviders,
            selectedProvider: selectedProvider,
            descriptor: descriptor)

        let hasTokenSwitcher = menu.items.contains { $0.view is TokenAccountSwitcherView }
        let hasCodexSwitcher = menu.items.contains { $0.view is CodexAccountSwitcherView }
        let switcherProvidersMatch = enabledProviders.map(\.instanceID) == self.lastSwitcherProviders
        let switcherUsageBarsShowUsedMatch = self.settings.usageBarsShowUsed == self.lastSwitcherUsageBarsShowUsed
        let switcherSelectionMatches = switcherSelection == self.lastMergedSwitcherSelection
        let switcherOverviewAvailabilityMatches = includesOverview == self.lastSwitcherIncludesOverview
        let menuLocalizationMatches = self.menuLocalizationSignature() == self.lastMenuLocalizationSignature
        let tokenSwitcherCompatible = tokenAccountDisplay == self.lastTokenAccountMenuDisplay &&
            ((tokenAccountDisplay?.showSwitcher == true && hasTokenSwitcher) ||
                (tokenAccountDisplay?.showSwitcher != true && !hasTokenSwitcher))
        let codexSwitcherCompatible = codexAccountDisplay == self.lastCodexAccountMenuDisplay &&
            ((codexAccountDisplay?.showSwitcher == true && hasCodexSwitcher) ||
                (codexAccountDisplay?.showSwitcher != true && !hasCodexSwitcher))
        let reusableRowWidthsMatch = self.reusableFixedWidthRows(in: menu).allSatisfy { item in
            guard let view = item.view else { return false }
            return abs(view.frame.width - menuWidth) <= 0.5
        }
        let providerSwitcherWidthMatches = (menu.items.first?.view as? ProviderSwitcherView).map { view in
            abs(view.frame.width - menuWidth) <= 0.5
        } ?? false
        let canSmartUpdate = self.shouldMergeIcons &&
            enabledProviders.count > 1 &&
            !isOverviewSelected &&
            switcherProvidersMatch &&
            switcherUsageBarsShowUsedMatch &&
            switcherSelectionMatches &&
            switcherOverviewAvailabilityMatches &&
            menuLocalizationMatches &&
            tokenSwitcherCompatible &&
            codexSwitcherCompatible &&
            reusableRowWidthsMatch &&
            !menu.items.isEmpty &&
            menu.items.first?.view is ProviderSwitcherView

        #if DEBUG
        if self.openMenus[ObjectIdentifier(menu)] != nil {
            self.menuLogger.debug(
                "populateMenu(open): provider=\(String(describing: provider)) " +
                    "display=\(enabledProviders.map(\.rawValue)) " +
                    "available=\(self.store.enabledProviders().map(\.rawValue)) " +
                    "selection=\(String(describing: switcherSelection)) " +
                    "last=\(String(describing: self.lastMergedSwitcherSelection)) " +
                    "smart=\(canSmartUpdate)")
        }
        #endif

        if canSmartUpdate {
            self.updateMenuContentPreservingSwitcher(
                menu,
                context: MenuUpdateContext(
                    provider: selectedProvider,
                    currentProvider: currentProvider,
                    switcherSelection: switcherSelection ?? .provider(currentProvider.instanceID),
                    menuWidth: menuWidth,
                    codexAccountDisplay: codexAccountDisplay,
                    tokenAccountDisplay: tokenAccountDisplay,
                    openAIContext: openAIContext,
                    descriptor: descriptor))
            return
        }

        let canPreserveProviderSwitcher = self.shouldMergeIcons &&
            enabledProviders.count > 1 &&
            switcherProvidersMatch &&
            switcherUsageBarsShowUsedMatch &&
            switcherOverviewAvailabilityMatches &&
            menuLocalizationMatches &&
            providerSwitcherWidthMatches &&
            !menu.items.isEmpty &&
            menu.items.first?.view is ProviderSwitcherView

        #if DEBUG
        if self.openMenus[ObjectIdentifier(menu)] != nil {
            self.menuLogger.debug(
                "populateMenu(open): preserveSwitcher=\(canPreserveProviderSwitcher) " +
                    "widthMatch=\(providerSwitcherWidthMatches)")
        }
        #endif

        if canPreserveProviderSwitcher {
            self.updateMenuContentPreservingSwitcher(
                menu,
                context: MenuUpdateContext(
                    provider: selectedProvider,
                    currentProvider: currentProvider,
                    switcherSelection: switcherSelection ?? .provider(currentProvider.instanceID),
                    menuWidth: menuWidth,
                    codexAccountDisplay: codexAccountDisplay,
                    tokenAccountDisplay: tokenAccountDisplay,
                    openAIContext: openAIContext,
                    descriptor: descriptor))
            return
        }

        #if DEBUG
        if self.openMenus[ObjectIdentifier(menu)] != nil, menu.items.first?.view is ProviderSwitcherView {
            self.menuLogger.debug("populateMenu(open): rebuilding whole menu and replacing provider switcher")
        }
        #endif
        MenuSwitchFlickerProbe.debugLog("full-rebuild-path \(String(describing: switcherSelection))")
        self.rebuildMenuContent(
            menu,
            context: MenuRebuildContext(
                enabledProviders: enabledProviders,
                includesOverview: includesOverview,
                switcherSelection: switcherSelection,
                currentProvider: currentProvider,
                selectedProvider: selectedProvider,
                menuWidth: menuWidth,
                codexAccountDisplay: codexAccountDisplay,
                tokenAccountDisplay: tokenAccountDisplay,
                openAIContext: openAIContext,
                descriptor: descriptor))
    }

    private func reusableFixedWidthRows(in menu: NSMenu) -> [NSMenuItem] {
        guard !menu.items.isEmpty else { return [] }

        var reusableRows: [NSMenuItem] = []
        var index = self.providerSwitcherContentStartIndex(in: menu)
        if index > 0 {
            reusableRows.append(menu.items[0])
        }
        if menu.items.count > index,
           menu.items[index].view is CodexAccountSwitcherView
        {
            reusableRows.append(menu.items[index])
            index += 2
        }
        if menu.items.count > index,
           menu.items[index].view is TokenAccountSwitcherView
        {
            reusableRows.append(menu.items[index])
        }
        return reusableRows
    }

    private func rebuildMenuContent(
        _ menu: NSMenu,
        context: MenuRebuildContext)
    {
        self.performMenuMutationWithoutAnimation {
            defer { self.flushHostedMenuRowRendering(in: menu) }
            let displacedSelection = self.lastMergedMenuContentSelection
            self.lastMergedMenuContentSelection = nil
            self.harvestRecyclableMenuCardViews(in: menu, fromIndex: 0, displacedSelection: displacedSelection)
            defer { self.clearMenuCardViewRecyclePool() }
            menu.removeAllItems()
            let contentSelection = context.switcherSelection ?? .provider(context.currentProvider.instanceID)
            self.addProviderSwitcherIfNeeded(
                to: menu,
                enabledProviders: context.enabledProviders,
                includesOverview: context.includesOverview,
                selection: context.switcherSelection ?? .provider(context.currentProvider.instanceID),
                width: context.menuWidth)
            // Track which providers the switcher was built with for smart update detection
            if self.shouldMergeIcons, context.enabledProviders.count > 1 {
                self.rememberMergedSwitcherState(
                    context.enabledProviders,
                    context.switcherSelection,
                    context.includesOverview)
            }
            if self.shouldMergeIcons,
               context.enabledProviders.count > 1,
               self.addCachedMergedSwitcherContent(
                   for: contentSelection,
                   to: menu,
                   menuWidth: context.menuWidth,
                   codexAccountDisplay: context.codexAccountDisplay,
                   tokenAccountDisplay: context.tokenAccountDisplay)
            {
                return
            }
            self.addCodexAccountSwitcherIfNeeded(
                to: menu,
                display: context.codexAccountDisplay,
                width: context.menuWidth)
            self.lastCodexAccountMenuDisplay = context.codexAccountDisplay
            self.addTokenAccountSwitcherIfNeeded(
                to: menu,
                display: context.tokenAccountDisplay,
                width: context.menuWidth)
            self.lastTokenAccountMenuDisplay = context.tokenAccountDisplay
            let menuContext = MenuCardContext(
                currentProvider: context.currentProvider,
                selectedProvider: context.selectedProvider,
                menuWidth: context.menuWidth,
                codexAccountDisplay: context.codexAccountDisplay,
                tokenAccountDisplay: context.tokenAccountDisplay,
                openAIContext: context.openAIContext)
            self.addPrimaryMenuContent(
                to: menu,
                context: menuContext,
                switcherSelection: contentSelection)
            self.addActionableSections(context.descriptor.sections, to: menu, width: context.menuWidth)
            self.cacheVisibleMergedSwitcherContent(
                in: menu,
                selection: contentSelection,
                contentStartIndex: self.providerSwitcherContentStartIndex(in: menu),
                menuWidth: context.menuWidth,
                contentVersion: self.menuSession.contentVersion)
        }
    }

    func openAIWebContext(
        currentProvider: UsageProvider,
        showAllAccounts: Bool) -> OpenAIWebContext
    {
        let codexProjection = self.store.codexConsumerProjectionIfNeeded(
            for: currentProvider,
            surface: .liveCard)
        let hasCreditsHistory = codexProjection?.hasCreditsHistory == true
        let hasUsageBreakdown = codexProjection?.hasUsageBreakdown == true
        let hasCostHistory = self.settings.costSummaryShowsSubmenu(for: currentProvider) &&
            (self.store.tokenSnapshot(for: currentProvider)?.daily.isEmpty == false)
        let canShowBuyCredits = self.settings.showOptionalCreditsAndExtraUsage &&
            codexProjection?.canShowBuyCredits == true
        let hasOpenAIWebMenuItems = !showAllAccounts &&
            (hasCreditsHistory || hasUsageBreakdown || hasCostHistory)
        return OpenAIWebContext(
            hasUsageBreakdown: hasUsageBreakdown,
            hasCreditsHistory: hasCreditsHistory,
            hasCostHistory: hasCostHistory,
            canShowBuyCredits: canShowBuyCredits,
            hasOpenAIWebMenuItems: hasOpenAIWebMenuItems)
    }

    private func addProviderSwitcherIfNeeded(
        to menu: NSMenu,
        enabledProviders: [UsageProvider],
        includesOverview: Bool,
        selection: ProviderSwitcherSelection,
        width: CGFloat)
    {
        guard self.shouldMergeIcons, enabledProviders.count > 1 else { return }
        let switcherItem = self.makeProviderSwitcherItem(
            providers: enabledProviders,
            includesOverview: includesOverview,
            selected: selection,
            menu: menu,
            width: width)
        menu.addItem(switcherItem)
        menu.addItem(.separator())
    }

    func addTokenAccountSwitcherIfNeeded(
        to menu: NSMenu,
        display: TokenAccountMenuDisplay?,
        width: CGFloat,
        captureMenu: NSMenu? = nil)
    {
        guard let display, display.showSwitcher else { return }
        let switcherItem = self.makeTokenAccountSwitcherItem(
            display: display,
            menu: captureMenu ?? menu,
            width: width)
        menu.addItem(switcherItem)
        menu.addItem(.separator())
    }

    func addCodexAccountSwitcherIfNeeded(
        to menu: NSMenu,
        display: CodexAccountMenuDisplay?,
        width: CGFloat,
        captureMenu: NSMenu? = nil)
    {
        guard let display, display.showSwitcher else { return }
        let switcherItem = self.makeCodexAccountSwitcherItem(
            display: display,
            menu: captureMenu ?? menu,
            width: width)
        menu.addItem(switcherItem)
        menu.addItem(.separator())
    }

    @discardableResult
    private func addOverviewRows(
        to menu: NSMenu,
        enabledProviders: [UsageProvider],
        menuWidth: CGFloat,
        captureMenu: NSMenu? = nil) -> Bool
    {
        // Rows may be built into a detached scratch menu for in-place reconciliation;
        // interaction closures must always reference the live menu they end up serving.
        let interactionMenu = captureMenu ?? menu
        let overviewProviders = self.settings.reconcileMergedOverviewSelectedProviders(
            activeProviders: enabledProviders)
        let rows: [(provider: UsageProvider, model: UsageMenuCardView.Model)] = overviewProviders
            .compactMap { provider in
                guard let model = self.menuCardModel(for: provider) else { return nil }
                guard !model.isOverviewErrorOnly else { return nil }
                return (provider: provider, model: model)
            }
        guard !rows.isEmpty else { return false }

        let t0 = CACurrentMediaTime()
        defer { self.logChartRenderDurationIfSlow("addOverviewRows(\(rows.count))", startedAt: t0) }

        for (index, row) in rows.enumerated() {
            let identifier = "\(Self.overviewRowIdentifierPrefix)\(row.provider.rawValue)"
            let storageText = self.store.storageFootprintText(for: row.provider)
            let submenu = self.makeOverviewRowSubmenu(
                provider: row.provider,
                model: row.model,
                width: menuWidth)
            let item = self.makeMenuCardItem(
                OverviewMenuCardRowView(model: row.model, storageText: storageText, width: menuWidth),
                id: identifier,
                width: menuWidth,
                heightCacheScope: row.provider.rawValue,
                heightCacheFingerprint: row.model.heightFingerprint(
                    section: "overview",
                    additional: [UsageMenuCardView.Model.heightFingerprintField("storage", storageText)]),
                submenu: submenu,
                containsInteractiveControls: row.model.subtitleStyle == .error || row.model.usesLiveSubtitle,
                usesGPUSelection: true,
                onClick: { [weak self, weak interactionMenu] in
                    guard let self, let interactionMenu else { return }
                    self.selectOverviewProvider(row.provider, menu: interactionMenu)
                })
            if submenu == nil {
                // Keep plain rows wired for keyboard activation and accessibility action paths.
                item.target = self
                item.action = #selector(self.selectOverviewProvider(_:))
            }
            menu.addItem(item)
            if index < rows.count - 1 {
                menu.addItem(.separator())
            }
        }
        return true
    }

    private func addOverviewEmptyState(to menu: NSMenu, enabledProviders: [UsageProvider]) {
        let resolvedProviders = self.settings.resolvedMergedOverviewProviders(
            activeProviders: enabledProviders,
            maxVisibleProviders: Self.maxOverviewProviders)
        let message = resolvedProviders.isEmpty
            ? L("No providers selected for Overview.")
            : L("No overview data available.")
        let item = NSMenuItem(title: message, action: nil, keyEquivalent: "")
        item.isEnabled = false
        item.representedObject = "overviewEmptyState"
        menu.addItem(item)
    }

    private func addMenuCards(to menu: NSMenu, context: MenuCardContext, captureMenu: NSMenu? = nil) -> Bool {
        let fleetProjection = self.fleetAccountProjection(for: context.currentProvider)
        if self.addFleetFallback(fleetProjection, to: menu, context: context) {
            return false
        }

        if let codexAccountDisplay = context.codexAccountDisplay, codexAccountDisplay.showAll {
            if !self.addCompactCodexAccountMenuIfPlanned(
                display: codexAccountDisplay,
                to: menu,
                captureMenu: captureMenu ?? menu,
                context: context)
            {
                self.addStackedCodexMenuCards(codexAccountDisplay, to: menu, context: context)
            }
            self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
            return false
        }

        // Eligible claude-swap rows take precedence over Claude token-account cards; otherwise
        // the stacked token-account branch below would return before rendering the adapter rows.
        if ClaudeSwapMenuPrecedence.prefersClaudeSwap(
            provider: context.currentProvider,
            accountCount: self.store.claudeSwapAccountSnapshots.count,
            showSingleAccount: self.settings.claudeSwapShowSingleAccount)
        {
            self.addClaudeSwapMenuCards(to: menu, captureMenu: captureMenu ?? menu, context: context)
            self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
            return false
        }

        if let tokenAccountDisplay = context.tokenAccountDisplay, tokenAccountDisplay.showAll {
            if self.addCompactTokenAccountMenuIfPlanned(
                display: tokenAccountDisplay,
                to: menu,
                captureMenu: captureMenu ?? menu,
                context: context)
            {
                self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
                return false
            }
            let accountSnapshots = tokenAccountDisplay.snapshots
            let cards = accountSnapshots.isEmpty
                ? []
                : accountSnapshots.compactMap { accountSnapshot in
                    self.tokenAccountMenuCardModel(
                        for: context.currentProvider,
                        accountSnapshot: accountSnapshot)
                }
            self.addStackedMenuCards(cards, to: menu, context: context)
            self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
            return false
        }

        // Provider-specific by design: Kilo organization scopes render as stacked account-like cards.
        if context.currentProvider == .kilo, self.store.kiloScopeSnapshots.count > 1 {
            let cards = self.store.kiloScopeSnapshots.compactMap { scope in
                self.menuCardModel(
                    for: .kilo,
                    snapshotOverride: scope.snapshot,
                    errorOverride: scope.errorMessage,
                    forceOverrideCard: scope.snapshot == nil)
            }
            self.addStackedMenuCards(cards, to: menu, context: context)
            self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
            return false
        }

        guard let model = self.menuCardModel(for: context.selectedProvider) else { return false }
        let renderedModel = self.menuCardRefreshMonitor.model(for: model.provider, fallback: model)
        if context.openAIContext.hasOpenAIWebMenuItems ||
            self.requiresSectionedMenuForProviderDerivedCost(provider: context.currentProvider)
        {
            let webItems = OpenAIWebMenuItems(
                hasUsageBreakdown: context.openAIContext.hasUsageBreakdown,
                hasCreditsHistory: context.openAIContext.hasCreditsHistory,
                hasCostHistory: context.openAIContext.hasCostHistory,
                canShowBuyCredits: context.openAIContext.canShowBuyCredits)
            self.addMenuCardSections(
                to: menu,
                model: model,
                layoutModel: renderedModel,
                width: context.menuWidth,
                webItems: webItems)
            self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
            return true
        }

        menu.addItem(self.makeMenuCardItem(
            UsageMenuCardView(model: model, layoutModel: renderedModel, width: context.menuWidth),
            id: "menuCard",
            width: context.menuWidth,
            heightCacheScope: context.currentProvider.rawValue,
            heightCacheFingerprint: renderedModel.heightFingerprint(section: "card"),
            containsInteractiveControls: true))
        self.addFleetAccountMenuCards(fleetProjection.additionalAccounts, to: menu, context: context)
        if self.addStorageMenuCardSection(to: menu, provider: context.currentProvider, width: context.menuWidth) {
            menu.addItem(.separator())
        }
        if context.openAIContext.canShowBuyCredits {
            menu.addItem(self.makeBuyCreditsItem())
        }
        menu.addItem(.separator())
        return false
    }

    private func addOpenAIWebItemsIfNeeded(
        to menu: NSMenu,
        currentProvider: UsageProvider,
        context: OpenAIWebContext,
        addedOpenAIWebItems: Bool)
    {
        guard context.hasOpenAIWebMenuItems else { return }
        if !addedOpenAIWebItems {
            // Only show these when we actually have additional data.
            if context.hasUsageBreakdown {
                _ = self.addUsageBreakdownSubmenu(to: menu)
            }
            if context.hasCreditsHistory {
                _ = self.addCreditsHistorySubmenu(to: menu)
            }
            if context.hasCostHistory {
                _ = self.addCostHistorySubmenu(to: menu, provider: currentProvider)
            }
        }
        if menu.items.last?.isSeparatorItem != true {
            menu.addItem(.separator())
        }
    }

    func addPrimaryMenuContent(
        to menu: NSMenu,
        context: MenuCardContext,
        switcherSelection: ProviderSwitcherSelection,
        captureMenu: NSMenu? = nil)
    {
        if switcherSelection == .overview {
            let enabledProviders = self.store.enabledFirstPartyProvidersForDisplay()
            if self.addOverviewRows(
                to: menu,
                enabledProviders: enabledProviders,
                menuWidth: context.menuWidth,
                captureMenu: captureMenu)
            {
                menu.addItem(.separator())
            } else {
                self.addOverviewEmptyState(to: menu, enabledProviders: enabledProviders)
                menu.addItem(.separator())
            }
        } else {
            let addedOpenAIWebItems = self.addMenuCards(to: menu, context: context, captureMenu: captureMenu)
            self.addOpenAIWebItemsIfNeeded(
                to: menu,
                currentProvider: context.currentProvider,
                context: context.openAIContext,
                addedOpenAIWebItems: addedOpenAIWebItems)
            self.addUsageHistoryClusterIfNeeded(to: menu, context: context)
        }
        self.addUserPluginMenuCards(to: menu, width: context.menuWidth)
    }

    func addActionableSections(
        _ sections: [MenuDescriptor.Section],
        to menu: NSMenu,
        width: CGFloat,
        captureMenu: NSMenu? = nil)
    {
        let actionableSections = sections.filter { section in section.entries.contains(where: \ .isActionable) }
        for (index, section) in actionableSections.enumerated() {
            for entry in section.entries {
                switch entry {
                case let .text(text, style):
                    if style == .secondary {
                        menu.addItem(self.makeWrappedSecondaryTextItem(text: text, width: width))
                        continue
                    }
                    let item = NSMenuItem(title: text, action: nil, keyEquivalent: "")
                    item.isEnabled = false
                    if style == .headline {
                        let font = NSFont.systemFont(ofSize: NSFont.systemFontSize, weight: .semibold)
                        item.attributedTitle = NSAttributedString(string: text, attributes: [.font: font])
                    } else if style == .secondary {
                        let font = NSFont.systemFont(ofSize: NSFont.smallSystemFontSize)
                        item.attributedTitle = NSAttributedString(
                            string: text,
                            attributes: [.font: font, .foregroundColor: NSColor.secondaryLabelColor])
                    }
                    menu.addItem(item)
                case let .action(title, action):
                    if action == .refresh {
                        let item = self.makePersistentRefreshItem(
                            title: L(title),
                            menu: captureMenu ?? menu,
                            width: width)
                        menu.addItem(item)
                        self.persistentRefreshItems.add(item)
                        continue
                    }
                    let localizedTitle = L(title)
                    let (selector, represented) = self.selector(for: action)
                    let item = NSMenuItem(title: localizedTitle, action: selector, keyEquivalent: "")
                    item.target = self
                    item.representedObject = represented
                    if let shortcut = self.shortcut(for: action) {
                        item.keyEquivalent = shortcut.key
                        item.keyEquivalentModifierMask = shortcut.modifiers
                    }
                    if let iconName = action.systemImageName,
                       let image = NSImage(systemSymbolName: iconName, accessibilityDescription: nil)
                    {
                        image.isTemplate = true
                        image.size = NSSize(width: 16, height: 16)
                        item.image = image
                    }
                    self.attachStatusComponentsSubmenuIfNeeded(
                        to: item,
                        action: action,
                        menu: captureMenu ?? menu,
                        width: width)
                    if case let .switchAccount(targetProvider) = action,
                       let subtitle = self.switchAccountSubtitle(for: targetProvider)
                    {
                        item.isEnabled = false
                        self.applySubtitle(subtitle, to: item, title: localizedTitle)
                    } else if case .addCodexAccount = action,
                              let subtitle = self.codexAddAccountSubtitle()
                    {
                        item.isEnabled = false
                        self.applySubtitle(subtitle, to: item, title: localizedTitle)
                    }
                    menu.addItem(item)
                case let .unavailable(title, tooltip):
                    let item = NSMenuItem(title: title, action: nil, keyEquivalent: "")
                    item.isEnabled = false
                    item.toolTip = tooltip
                    menu.addItem(item)
                case let .submenu(title, systemImageName, submenuItems):
                    let item = NSMenuItem(title: title, action: nil, keyEquivalent: "")
                    if let systemImageName,
                       let image = NSImage(systemSymbolName: systemImageName, accessibilityDescription: nil)
                    {
                        image.isTemplate = true
                        image.size = NSSize(width: 16, height: 16)
                        item.image = image
                    }
                    let submenu = NSMenu(title: title)
                    submenu.autoenablesItems = false
                    for submenuItem in submenuItems {
                        let child = NSMenuItem(title: submenuItem.title, action: nil, keyEquivalent: "")
                        child.state = submenuItem.isChecked ? .on : .off
                        child.isEnabled = submenuItem.isEnabled
                        if let action = submenuItem.action {
                            let (selector, represented) = self.selector(for: action)
                            child.action = selector
                            child.target = self
                            child.representedObject = represented
                        }
                        submenu.addItem(child)
                    }
                    item.submenu = submenu
                    menu.addItem(item)
                case .divider:
                    menu.addItem(.separator())
                }
            }
            if index < actionableSections.count - 1 {
                menu.addItem(.separator())
            }
        }
    }

    private func makeWrappedSecondaryTextItem(text: String, width: CGFloat) -> NSMenuItem {
        let item = NSMenuItem(title: "", action: nil, keyEquivalent: "")
        let view = self.makeWrappedSecondaryTextView(text: text)
        let height = self.menuTextItemHeight(for: view, width: width)
        view.frame = NSRect(origin: .zero, size: NSSize(width: width, height: height))
        item.view = view
        item.isEnabled = false
        item.toolTip = text
        return item
    }

    private func makeWrappedSecondaryTextView(text: String) -> NSView {
        let container = NSView()
        container.translatesAutoresizingMaskIntoConstraints = false

        let textField = NSTextField(wrappingLabelWithString: text)
        textField.font = NSFont.menuFont(ofSize: NSFont.smallSystemFontSize)
        textField.textColor = NSColor.secondaryLabelColor
        textField.lineBreakMode = .byWordWrapping
        textField.maximumNumberOfLines = 0
        textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        textField.translatesAutoresizingMaskIntoConstraints = false

        container.addSubview(textField)
        // macos-smell:disable MACOS005
        NSLayoutConstraint.activate([
            textField.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 18),
            textField.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -10),
            textField.topAnchor.constraint(equalTo: container.topAnchor, constant: 2),
            textField.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: -2),
        ])

        return container
    }

    private func menuTextItemHeight(for view: NSView, width: CGFloat) -> CGFloat {
        view.frame = NSRect(origin: .zero, size: NSSize(width: width, height: 1))
        view.layoutSubtreeIfNeeded()
        return max(1, ceil(view.fittingSize.height))
    }

    func makeMenu(for provider: UsageProvider?) -> NSMenu {
        let menu = self.makeBaseMenu()
        if let provider {
            self.menuProviders[ObjectIdentifier(menu)] = provider.instanceID
        }
        return menu
    }

    private func makeBaseMenu() -> NSMenu {
        let menu = StatusItemMenu()
        menu.autoenablesItems = false
        menu.delegate = self
        menu.persistentActionDelegate = self
        StatusMenuAppearance.pin(menu)
        return menu
    }

    private func makeProviderSwitcherItem(
        providers: [UsageProvider],
        includesOverview: Bool,
        selected: ProviderSwitcherSelection,
        menu: NSMenu,
        width: CGFloat) -> NSMenuItem
    {
        let view = ProviderSwitcherView(
            providers: providers,
            selected: selected,
            includesOverview: includesOverview,
            width: width,
            showsIcons: self.settings.switcherShowsIcons,
            iconProvider: { [weak self] provider in
                self?.switcherIcon(for: provider) ?? NSImage()
            },
            weeklyRemainingProvider: { [weak self] provider in
                self?.switcherWeeklyRemaining(for: provider)
            },
            onSelect: { [weak self, weak menu] selection in
                guard let self, let menu else { return }
                MenuSwitchFlickerProbe.debugLog("onSelect \(selection)")
                var provider: UsageProvider?
                self.preservingMergedSwitcherContentCachesDuringInvalidation {
                    switch selection {
                    case .overview:
                        self.settings.mergedMenuLastSelectedWasOverview = true
                        provider = self.resolvedMenuProvider()
                    case let .provider(selectedProvider):
                        self.settings.mergedMenuLastSelectedWasOverview = false
                        self.selectedMenuProvider = selectedProvider
                        provider = selectedProvider.firstPartyProvider
                    }
                    switch selection {
                    case .overview:
                        // Provider-specific by design: Codex is the persisted fallback for an empty overview.
                        self.lastMenuProvider = (provider ?? .codex).instanceID
                    case let .provider(provider):
                        self.lastMenuProvider = provider
                    }
                    self.lastMergedSwitcherSelection = selection
                    self.refreshProviderSelectionDependentUI(deferRendering: true)
                }
                self.requestProviderSwitcherMenuRebuild(menu, provider: provider)
            })
        let item = NSMenuItem()
        item.title = ""
        item.view = view
        item.isEnabled = false
        return item
    }

    private func makeTokenAccountSwitcherItem(
        display: TokenAccountMenuDisplay,
        menu: NSMenu,
        width: CGFloat) -> NSMenuItem
    {
        let view = TokenAccountSwitcherView(
            accounts: display.accounts,
            selectedIndex: display.activeIndex,
            width: width,
            onSelect: { [weak self, weak menu] index -> Task<Void, Never>? in
                guard let self, let menu else { return nil }
                guard display.accounts.indices.contains(index) else { return nil }
                let selectedAccount = display.accounts[index]
                self.advanceMenuInteraction(for: menu)
                self.settings.setActiveTokenAccountIndex(index, for: display.provider)
                self.store.activateCachedTokenAccountSnapshot(
                    provider: display.provider,
                    accountID: selectedAccount.id)
                self.applyIcon(phase: nil)
                self.deferSwitcherMenuRebuildIfStillVisible(menu, provider: display.provider)
                return Task { @MainActor [weak self, weak menu] in
                    guard let self else { return }
                    await ProviderInteractionContext.$current.withValue(.userInitiated) {
                        await self.store.refreshProvider(display.provider)
                    }
                    guard let menu else { return }
                    self.deferSwitcherMenuRebuildIfStillVisible(menu, provider: display.provider)
                }
            })
        let item = NSMenuItem()
        item.title = ""
        item.view = view
        item.isEnabled = false
        return item
    }

    private func makeCodexAccountSwitcherItem(
        display: CodexAccountMenuDisplay,
        menu: NSMenu,
        width: CGFloat) -> NSMenuItem
    {
        let view = CodexAccountSwitcherView(
            accounts: display.accounts,
            selectedAccountID: display.activeVisibleAccountID,
            width: width,
            onSelect: { [weak self, weak menu] account in
                guard let self else { return }
                self.handleCodexVisibleAccountSelection(account, menu: menu)
            })
        let item = NSMenuItem()
        item.title = ""
        item.view = view
        item.isEnabled = false
        return item
    }

    @discardableResult
    private func handleCodexVisibleAccountSelection(_ account: CodexVisibleAccount, menu: NSMenu?) -> Bool {
        // Provider-specific by design: managed Codex selection rebuilds after account-scoped reconciliation.
        let visibleAccountID = account.id
        self.advanceMenuInteraction(for: menu)
        self.settings.selectDisplayedCodexVisibleAccount(account)
        if self.store.prepareCodexAccountScopedRefreshIfNeeded(), let menu {
            self.deferSwitcherMenuRebuildIfStillVisible(menu, provider: .codex)
        }
        let store = self.store
        let settings = self.settings
        Task { @MainActor [weak controller = self, weak menu, store, settings] in
            await ProviderInteractionContext.$current.withValue(.userInitiated) {
                await store.refreshCodexAccountScopedState(
                    allowDisabled: true,
                    phaseDidChange: { [weak controller, weak menu, settings] _ in
                        guard let controller, let menu else { return }
                        guard settings.codexVisibleAccountProjection.activeVisibleAccountID == visibleAccountID
                        else {
                            return
                        }
                        controller.refreshOpenMenuIfStillVisible(menu, provider: .codex)
                    })
            }
        }
        return true
    }

    func resolvedMenuProvider(enabledProviders: [UsageProvider]? = nil) -> UsageProvider? {
        let enabled = enabledProviders ?? self.store.enabledFirstPartyProvidersForDisplay()
        if enabled.isEmpty {
            return .codex // Provider-specific by design: an empty first-party menu preserves the Codex default.
        }
        if let selected = self.selectedMenuProvider?.firstPartyProvider, enabled.contains(selected) {
            return selected
        }
        // Prefer an available provider so the default menu content matches the status icon.
        // Falls back to first display provider when all lack credentials.
        return enabled.first(where: { self.store.isProviderAvailable($0) }) ?? enabled.first
    }

    func includesOverviewTab(enabledProviders: [UsageProvider]) -> Bool {
        !self.settings.resolvedMergedOverviewProviders(
            activeProviders: enabledProviders,
            maxVisibleProviders: Self.maxOverviewProviders).isEmpty
    }

    func resolvedSwitcherSelection(
        enabledProviders: [UsageProvider],
        includesOverview: Bool) -> ProviderSwitcherSelection
    {
        if includesOverview, self.settings.mergedMenuLastSelectedWasOverview {
            return .overview
        }
        return .provider((self.resolvedMenuProvider(enabledProviders: enabledProviders) ?? .codex).instanceID)
    }

    func menuProvider(for menu: NSMenu) -> UsageProvider? {
        if self.shouldMergeIcons {
            return self.resolvedMenuProvider()
        }
        if let provider = self.menuProviders[ObjectIdentifier(menu)] {
            return provider.firstPartyProvider
        }
        if menu === self.fallbackMenu {
            return nil
        }
        return self.store.enabledFirstPartyProvidersForDisplay().first ?? .codex
    }

    private func scheduleOpenMenuRefresh(for menu: NSMenu) {
        // Queue refresh work only when visible menu data is missing or stale. Here "stale" means the last
        // provider fetch failed and needs a retry; periodic freshness is handled by the refresh timer.
        // AppKit menu tracking is modal, so starting provider refreshes while it is active can make the menu
        // feel frozen and can block keyboard focus from returning.
        // Exception: when `refreshAllProvidersOnMenuOpen` is enabled, every enabled provider is refreshed on
        // open regardless of freshness — still after the delay below, and still via the light usage-only
        // primitive so the OpenAI dashboard scrape stays deferred until the menu closes.
        let providersNeedingRetryAtOpen = self.delayedRefreshRetryProviders(for: menu).filter {
            self.store.needsUsageRefreshRetry(for: $0)
        }
        if !providersNeedingRetryAtOpen.isEmpty {
            self.deferMenuInteractionRefreshIfNeeded(providers: providersNeedingRetryAtOpen)
        }
        let key = ObjectIdentifier(menu)
        self.menuRefreshTasks[key]?.cancel()
        self.menuRefreshTasks[key] = Task { @MainActor [weak self, weak menu] in
            guard let self, let menu else { return }
            try? await Task.sleep(for: Self.menuOpenRefreshDelay)
            guard !Task.isCancelled else { return }
            guard self.isMenuRefreshEnabled else { return }
            #if DEBUG
            self.onDelayedMenuRefreshAttemptForTesting?()
            #endif
            guard self.openMenus[ObjectIdentifier(menu)] != nil else { return }
            let refreshAllOnOpen = self.settings.refreshAllProvidersOnMenuOpen
            let enabledProviders = self.store.enabledProvidersForBackgroundWork()
            let visibleProviders = self.delayedRefreshRetryProviders(for: menu)
            let visibleInstanceIDs = visibleProviders.map(\.instanceID)
            let plan = MenuOpenRefreshPlan.resolve(.init(
                refreshAllOnOpen: refreshAllOnOpen,
                enabledProviders: enabledProviders,
                visibleProviders: visibleInstanceIDs,
                refreshingProviders: self.store.refreshingProviders,
                staleProviders: Set(visibleProviders.filter { self.store.isStale(provider: $0) }.map(\.instanceID)),
                missingProviders: Set(visibleProviders
                    .filter { !self.store.hasSatisfiedUsageFetch(for: $0) }
                    .map(\.instanceID))))
            if plan.refreshCodexDashboard {
                self.deferOpenAIDashboardRefreshUntilMenuCloses(reason: "refresh all")
            }
            let retryInstanceIDs = plan.providers
            let retryProviders = retryInstanceIDs.compactMap(\.firstPartyProvider)
            guard !retryInstanceIDs.isEmpty else {
                self.clearSatisfiedDeferredMenuInteractionRefreshes(
                    for: self.delayedRefreshRetryProviders(for: menu).map(\.instanceID))
                // Ordinary store changes intentionally stay queued until the next open. Rebuilding here
                // made first-open work such as the storage scan flash the visible menu after 1.2 seconds.
                if !providersNeedingRetryAtOpen.isEmpty, self.menuNeedsRefresh(menu) {
                    self.scheduleOpenMenuRebuildIfStillVisible(
                        menu,
                        provider: self.menuProvider(for: menu),
                        resyncReadinessBaselineAfterRebuild: self.openMenus.count == 1)
                }
                return
            }
            self.deferredMenuInteractionRefreshProviders.formUnion(retryInstanceIDs)
            await ProviderInteractionContext.$current.withValue(.background) {
                if plan.scheduling == .concurrent {
                    // Refresh concurrently so one slow provider doesn't delay the rest, mirroring the
                    // periodic refresh in `UsageStore.runRefresh`. `coalesceIfRefreshing` makes each call
                    // wait for any in-flight refresh (e.g. a manual refresh) instead of overriding it.
                    await withTaskGroup(of: Void.self) { group in
                        for provider in retryProviders {
                            group.addTask {
                                await self.store.refreshProvider(provider, coalesceIfRefreshing: true)
                            }
                        }
                    }
                } else {
                    for provider in retryProviders {
                        guard !Task.isCancelled else { return }
                        await self.store.refreshProvider(provider, coalesceIfRefreshing: true)
                    }
                }
            }
            let stillNeedsRetry = retryProviders.contains {
                self.store.needsUsageRefreshRetry(for: $0)
            }
            if !stillNeedsRetry {
                self.clearSatisfiedDeferredMenuInteractionRefreshes(for: retryInstanceIDs)
            }
            guard !Task.isCancelled else { return }
            guard self.openMenus[ObjectIdentifier(menu)] != nil else { return }
            self.invalidateMenus(
                refreshOpenMenus: true,
                deferOpenParentMenuRebuild: false,
                allowStaleContentDuringDataRefresh: true)
        }
    }

    private func menuNeedsDelayedRefreshRetry(for menu: NSMenu) -> Bool {
        let providersToCheck = self.delayedRefreshRetryProviders(for: menu)
        guard !providersToCheck.isEmpty else { return false }
        return providersToCheck.contains { provider in
            self.store.needsUsageRefreshRetry(for: provider)
        }
    }

    private func delayedRefreshRetryProviders(for menu: NSMenu) -> [UsageProvider] {
        self.renderedProviders(for: menu)
    }

    func renderedProviders(for menu: NSMenu) -> [UsageProvider] {
        let enabledProviders = self.store.enabledFirstPartyProvidersForDisplay()
        guard !enabledProviders.isEmpty else { return [] }
        let includesOverview = self.includesOverviewTab(enabledProviders: enabledProviders)

        if self.shouldMergeIcons,
           enabledProviders.count > 1,
           self.resolvedSwitcherSelection(
               enabledProviders: enabledProviders,
               includesOverview: includesOverview) == .overview
        {
            return self.settings.resolvedMergedOverviewProviders(
                activeProviders: enabledProviders,
                maxVisibleProviders: Self.maxOverviewProviders)
        }

        if let provider = self.menuProvider(for: menu)
            ?? self.resolvedMenuProvider(enabledProviders: enabledProviders)
        {
            return [provider]
        }
        return enabledProviders
    }

    private func addMenuCardSections(
        to menu: NSMenu,
        model: UsageMenuCardView.Model,
        layoutModel: UsageMenuCardView.Model,
        width: CGFloat,
        webItems: OpenAIWebMenuItems)
    {
        let provider = layoutModel.provider
        let hasCredits = layoutModel.creditsText != nil
        let hasExtraUsage = layoutModel.providerCost != nil
        let hasCost = layoutModel.tokenUsage != nil
        let bottomPadding = CGFloat(hasCredits ? 4 : 6)
        let sectionSpacing = CGFloat(6)
        let creditsBottomPadding = bottomPadding
        func addSectionSeparator() {
            guard menu.items.last?.isSeparatorItem != true else { return }
            menu.addItem(.separator())
        }

        if layoutModel.hasUsageContent {
            let usageView = UsageMenuCardHeaderAndUsageSectionView(
                model: model,
                layoutModel: layoutModel,
                bottomPadding: bottomPadding,
                width: width)
            let usageSubmenu = self.makeUsageSubmenu(
                provider: provider,
                snapshot: self.store.snapshot(for: provider.instanceID),
                webItems: webItems,
                width: width)
            menu.addItem(self.makeMenuCardItem(
                usageView,
                id: "menuCardUsage",
                width: width,
                heightCacheScope: provider.rawValue,
                heightCacheFingerprint: layoutModel.heightFingerprint(section: "usage"),
                submenu: usageSubmenu,
                containsInteractiveControls: true))
        } else {
            let headerView = UsageMenuCardHeaderSectionView(
                model: layoutModel,
                showDivider: false,
                width: width)
            menu.addItem(self.makeMenuCardItem(
                headerView,
                id: "menuCardHeader",
                width: width,
                heightCacheScope: provider.rawValue,
                heightCacheFingerprint: layoutModel.heightFingerprint(section: "header"),
                containsInteractiveControls: true))
        }

        if self.addStorageMenuCardSection(to: menu, provider: provider, width: width),
           hasCredits || hasExtraUsage
        {
            addSectionSeparator()
        }

        if hasCredits {
            addSectionSeparator()
            let creditsView = UsageMenuCardCreditsSectionView(
                model: model,
                showBottomDivider: false,
                topPadding: sectionSpacing,
                bottomPadding: creditsBottomPadding,
                width: width)
            let creditsSubmenu = webItems.hasCreditsHistory ? self.makeCreditsHistorySubmenu(width: width) : nil
            menu.addItem(self.makeMenuCardItem(
                creditsView,
                id: "menuCardCredits",
                width: width,
                heightCacheScope: provider.rawValue,
                heightCacheFingerprint: layoutModel.heightFingerprint(section: "credits"),
                submenu: creditsSubmenu))
            if webItems.canShowBuyCredits {
                menu.addItem(self.makeBuyCreditsItem())
            }
        }
        if hasExtraUsage {
            addSectionSeparator()
            let extraUsageSubmenu = self.makeOpenAIAPIUsageSubmenu(provider: provider, width: width)
            let extraUsageView = UsageMenuCardExtraUsageSectionView(
                model: model,
                topPadding: sectionSpacing,
                bottomPadding: bottomPadding,
                width: width)
            menu.addItem(self.makeMenuCardItem(
                extraUsageView,
                id: "menuCardExtraUsage",
                width: width,
                heightCacheScope: provider.rawValue,
                heightCacheFingerprint: layoutModel.heightFingerprint(section: "extraUsage"),
                submenu: extraUsageSubmenu))
        }
        if hasCost {
            addSectionSeparator()
            let costSubmenu = webItems.hasCostHistory ? self
                .makeCostHistorySubmenu(provider: provider, width: width) : nil
            menu.addItem(self.makeCostMenuCardItem(
                model: model,
                submenu: costSubmenu,
                width: width))
        }
        if !hasCredits, webItems.hasCreditsHistory, self.settings.showOptionalCreditsAndExtraUsage {
            addSectionSeparator()
            _ = self.addCreditsHistorySubmenu(to: menu)
        }
        if !hasCredits, webItems.canShowBuyCredits {
            menu.addItem(self.makeBuyCreditsItem())
        }
    }

    private func switcherIcon(for provider: UsageProvider) -> NSImage {
        if let brand = ProviderBrandIcon.image(for: provider) {
            return brand
        }

        // Fallback to the dynamic icon renderer if resources are missing (e.g. dev bundle mismatch).
        let snapshot = self.store.snapshot(for: provider.instanceID)
        let showUsed = self.settings.usageBarsShowUsed
        let style = self.store.style(for: provider)
        let now = Date()
        let resolved = snapshot.map {
            IconRemainingResolver.resolvedPercents(
                snapshot: $0,
                style: style,
                showUsed: showUsed,
                secondaryOverrideWindowID: self.settings.copilotIconSecondaryWindowOverrideID(snapshot: $0),
                now: now)
        }
        let primary = resolved?.primary
        let weekly = resolved?.secondary
        let creditsProjection = self.store.codexConsumerProjectionIfNeeded(
            for: provider,
            surface: .menuBar,
            snapshotOverride: snapshot,
            now: now)
        let credits = creditsProjection?.menuBarFallback == .creditsBalance
            ? self.store.codexMenuBarCreditsRemaining(
                snapshotOverride: snapshot,
                now: now)
            : nil
        let stale = self.store.isStale(provider: provider)
        let indicator = self.store.statusIndicator(for: provider)
        let image = IconRenderer.makeIcon(
            primaryRemaining: primary,
            weeklyRemaining: weekly,
            creditsRemaining: credits,
            stale: stale,
            style: style,
            blink: 0,
            wiggle: 0,
            tilt: 0,
            statusIndicator: indicator,
            hideCritters: self.settings.menuBarHidesCritters)
        image.isTemplate = true
        return image
    }

    private func makeBuyCreditsItem() -> NSMenuItem {
        let item = NSMenuItem(
            title: L("Buy Credits..."),
            action: #selector(self.openCreditsPurchase),
            keyEquivalent: "")
        item.target = self
        if let image = NSImage(systemSymbolName: "plus.circle", accessibilityDescription: nil) {
            image.isTemplate = true
            image.size = NSSize(width: 16, height: 16)
            item.image = image
        }
        return item
    }

    @discardableResult
    private func addCreditsHistorySubmenu(to menu: NSMenu) -> Bool {
        guard let submenu = self.makeCreditsHistorySubmenu(width: self.renderedMenuWidth(for: menu))
        else { return false }
        let item = NSMenuItem(title: L("Credits history"), action: nil, keyEquivalent: "")
        item.isEnabled = true
        item.submenu = submenu
        menu.addItem(item)
        return true
    }

    @discardableResult
    private func addUsageBreakdownSubmenu(to menu: NSMenu) -> Bool {
        guard let submenu = self.makeUsageBreakdownSubmenu(width: self.renderedMenuWidth(for: menu))
        else { return false }
        let item = NSMenuItem(title: L("Usage breakdown"), action: nil, keyEquivalent: "")
        item.isEnabled = true
        item.submenu = submenu
        menu.addItem(item)
        return true
    }

    @discardableResult
    private func addCostHistorySubmenu(to menu: NSMenu, provider: UsageProvider) -> Bool {
        guard let submenu = self.makeCostHistorySubmenu(provider: provider, width: self.renderedMenuWidth(for: menu))
        else { return false }
        let days = self.store.settings.costUsageHistoryDays
        let title = days == 1 ? L("Usage history (today)") : String(format: L("Usage history (%d days)"), days)
        let item = NSMenuItem(title: title, action: nil, keyEquivalent: "")
        item.isEnabled = true
        item.submenu = submenu
        menu.addItem(item)
        return true
    }

    private func makeUsageSubmenu(
        provider: UsageProvider,
        snapshot: UsageSnapshot?,
        webItems: OpenAIWebMenuItems,
        width: CGFloat? = nil) -> NSMenu?
    {
        if webItems.hasUsageBreakdown {
            return self.makeUsageBreakdownSubmenu(width: width)
        }
        // Provider-specific by design: OpenAI and Mistral attach cost history to their provider usage row.
        if provider == .openai {
            return self.makeOpenAIAPIUsageSubmenu(provider: provider, width: width)
        }
        // Mistral's top usage pane has no rate-limit bars of its own, so its cost history hangs
        // off this row instead. Other `tokenCostRequiresProviderSnapshot` providers (e.g.
        // opencodego) show real rate-limit bars here and get their own "Cost" row instead
        // (see `makeCostMenuCardItem`), matching Codex/Claude's structure.
        if provider == .mistral {
            return self.makeCostHistorySubmenu(provider: provider, width: width)
        }
        return nil
    }

    private func makeUsageBreakdownSubmenu(width: CGFloat? = nil) -> NSMenu? {
        let breakdown = OpenAIDashboardDailyBreakdown.removingSkillUsageServices(
            from: self.store.openAIDashboard?.usageBreakdown ?? [])
        guard !breakdown.isEmpty else { return nil }
        if let width {
            return self.makeHostedSubviewPlaceholderMenu(chartID: Self.usageBreakdownChartID, width: width)
        }
        return self.makeHostedSubviewPlaceholderMenu(chartID: Self.usageBreakdownChartID)
    }

    private func makeCreditsHistorySubmenu(width: CGFloat? = nil) -> NSMenu? {
        guard !(self.store.openAIDashboard?.dailyBreakdown ?? []).isEmpty else { return nil }
        if let width {
            return self.makeHostedSubviewPlaceholderMenu(chartID: Self.creditsHistoryChartID, width: width)
        }
        return self.makeHostedSubviewPlaceholderMenu(chartID: Self.creditsHistoryChartID)
    }

    func makeCostHistorySubmenu(provider: UsageProvider, width: CGFloat? = nil) -> NSMenu? {
        guard ProviderDescriptorRegistry.descriptor(for: provider).tokenCost.supportsTokenCost else { return nil }
        guard self.tokenSnapshotForCostHistorySubmenu(provider: provider)?.daily.isEmpty == false else { return nil }
        if let width {
            return self.makeHostedSubviewPlaceholderMenu(
                chartID: Self.costHistoryChartID,
                provider: provider,
                width: width)
        }
        return self.makeHostedSubviewPlaceholderMenu(chartID: Self.costHistoryChartID, provider: provider)
    }

    func tokenSnapshotForCostHistorySubmenu(provider: UsageProvider) -> CostUsageTokenSnapshot? {
        let projected = self.store.tokenSnapshot(
            fromProviderSnapshot: self.store.snapshot(for: provider.instanceID),
            provider: provider)
        if UsageStore.tokenCostRequiresProviderSnapshot(provider) {
            return projected
        }
        return projected ?? self.store.tokenSnapshot(for: provider)
    }

    func makeOpenAIAPIUsageSubmenu(provider: UsageProvider, width: CGFloat? = nil) -> NSMenu? {
        guard self.hasOpenAIAPIUsageSubmenu(provider: provider) else { return nil }
        return self.makeCostHistorySubmenu(provider: provider, width: width)
    }

    private func hasOpenAIAPIUsageSubmenu(provider: UsageProvider) -> Bool {
        // Provider-specific by design: OpenAI Admin API daily data gates its native usage submenu.
        provider == .openai && self.tokenSnapshotForCostHistorySubmenu(provider: provider)?.daily.isEmpty == false
    }

    /// Unlike `makeUsageSubmenu`'s and `tokenCostMenuSectionEnabled`'s provider checks, this one
    /// intentionally reuses `tokenCostRequiresProviderSnapshot`: any provider whose cost is
    /// sourced by projecting a snapshot field (rather than the CostUsageFetcher pipeline) can only
    /// render that cost through `addMenuCardSections`'s sectioned layout, so the two concepts are
    /// genuinely coupled here, not coincidentally aliased. The name is deliberately broader than
    /// "top-pane submenu" — opencodego satisfies this via its collapsible "Cost" row, not a
    /// provider-native top-pane submenu like openai/mistral.
    private func requiresSectionedMenuForProviderDerivedCost(provider: UsageProvider) -> Bool {
        UsageStore.tokenCostRequiresProviderSnapshot(provider) &&
            self.tokenSnapshotForCostHistorySubmenu(provider: provider)?.daily.isEmpty == false
    }

    func makeStorageBreakdownSubmenu(provider: UsageProvider, width: CGFloat? = nil) -> NSMenu? {
        guard self.store.storageFootprint(for: provider)?.components.isEmpty == false else { return nil }
        if let width {
            return self.makeHostedSubviewPlaceholderMenu(
                chartID: Self.storageBreakdownID,
                provider: provider,
                width: width)
        }
        return self.makeHostedSubviewPlaceholderMenu(chartID: Self.storageBreakdownID, provider: provider)
    }

    /// Providers that surface the live component list as a native submenu. Every other provider
    /// keeps the plain "Status Page" link that opens the website. Kept deliberately small: these
    /// are the statuspage.io/incident.io feeds we actively curate and trust to render well.
    /// Provider-specific by design: these four curated status feeds expose component trees rendered by the app.
    static let statusComponentsSubmenuProviders: Set<UsageProvider> = [.claude, .codex, .augment, .zoommate]

    /// Filters `components` down to a provider's descriptor-owned named allowlist, if configured;
    /// returns `components` unchanged when the provider has no allowlist. Matching is by exact
    /// `name` equality at the top level only (groups and leaves alike).
    static func filterStatusComponents(
        _ components: [ProviderStatusComponent],
        for provider: UsageProvider) -> [ProviderStatusComponent]
    {
        let metadata = ProviderDescriptorRegistry.descriptor(for: provider).metadata
        guard let allowlist = metadata.statusComponentAllowlist else { return components }
        return components.filter { allowlist.contains($0.name) }
    }

    /// Builds the status submenu (component rows + a website link) for the curated providers in
    /// `statusComponentsSubmenuProviders`. Gated on the provider being in that allowlist (and
    /// having a component feed) rather than on components being loaded yet: status is fetched
    /// asynchronously, so gating on loaded components would leave the row as a plain link for any
    /// provider whose first fetch hasn't landed at menu-build time. The submenu hydrates from the
    /// live component list each time it opens (and shows just the website link until the first
    /// fetch lands). Returns nil for all other providers, which keep the plain status-page link.
    /// For curated providers, turns the "Status Page" row into a submenu of live component
    /// statuses instead of a direct website link (the link moves to the bottom of the submenu).
    func attachStatusComponentsSubmenuIfNeeded(
        to item: NSMenuItem,
        action: MenuDescriptor.MenuAction,
        menu: NSMenu,
        width: CGFloat)
    {
        guard action == .statusPage,
              let statusProvider = self.menuProvider(for: menu) ?? self.lastMenuProvider?.firstPartyProvider,
              let submenu = self.makeStatusComponentsSubmenu(provider: statusProvider, width: width)
        else { return }
        item.action = nil
        item.submenu = submenu
    }

    func makeStatusComponentsSubmenu(provider: UsageProvider, width: CGFloat? = nil) -> NSMenu? {
        guard self.store.statusChecksEnabled else { return nil }
        guard Self.statusComponentsSubmenuProviders.contains(provider) else { return nil }
        guard ProviderDescriptorRegistry.descriptor(for: provider).metadata.statusPageURL != nil else { return nil }
        if let width {
            return self.makeHostedSubviewPlaceholderMenu(
                chartID: Self.statusComponentsID,
                provider: provider,
                width: width)
        }
        return self.makeHostedSubviewPlaceholderMenu(chartID: Self.statusComponentsID, provider: provider)
    }

    private func isOpenAIWebSubviewMenu(_ menu: NSMenu) -> Bool {
        let ids: Set = [
            Self.usageBreakdownChartID,
            Self.creditsHistoryChartID,
        ]
        return menu.items.contains { item in
            guard let id = item.representedObject as? String else { return false }
            return ids.contains(id)
        }
    }

    @objc func menuCardNoOp(_ sender: NSMenuItem) {
        _ = sender
    }
}
