import CodexBarCore
import Foundation
import Testing
@testable import CodexBar

// swiftlint:disable:next type_body_length
struct UsageStorePlanUtilizationTests {
    @Test
    func `coalesces changed usage within hour into single entry`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let hourStart = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone(secondsFromGMT: 0),
            year: 2026,
            month: 3,
            day: 17,
            hour: 10)))
        let first = planEntry(at: hourStart, usedPercent: 10)
        let second = planEntry(at: hourStart.addingTimeInterval(25 * 60), usedPercent: 35)

        let initial = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: [],
                entry: first))
        let updated = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: initial,
                entry: second))

        #expect(updated.count == 1)
        #expect(updated.last == second)
    }

    @Test
    func `changed reset boundary within hour appends new entry`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let hourStart = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone(secondsFromGMT: 0),
            year: 2026,
            month: 3,
            day: 17,
            hour: 10)))
        let first = planEntry(
            at: hourStart.addingTimeInterval(5 * 60),
            usedPercent: 82,
            resetsAt: hourStart.addingTimeInterval(30 * 60))
        let second = planEntry(
            at: hourStart.addingTimeInterval(35 * 60),
            usedPercent: 4,
            resetsAt: hourStart.addingTimeInterval(5 * 60 * 60))

        let initial = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: [],
                entry: first))
        let updated = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: initial,
                entry: second))

        #expect(updated.count == 2)
        #expect(updated[0] == first)
        #expect(updated[1] == second)
    }

    @Test
    func `first known reset boundary within hour replaces earlier provisional peak even when usage drops`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let hourStart = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone(secondsFromGMT: 0),
            year: 2026,
            month: 3,
            day: 17,
            hour: 10)))
        let first = planEntry(
            at: hourStart.addingTimeInterval(5 * 60),
            usedPercent: 82,
            resetsAt: nil)
        let second = planEntry(
            at: hourStart.addingTimeInterval(35 * 60),
            usedPercent: 4,
            resetsAt: hourStart.addingTimeInterval(5 * 60 * 60))

        let initial = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: [],
                entry: first))
        let updated = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: initial,
                entry: second))

        #expect(updated.count == 1)
        #expect(updated[0] == second)
    }

    @Test
    func `trims entry history to retention limit`() throws {
        let maxSamples = UsageStore._planUtilizationMaxSamplesForTesting
        let base = Date(timeIntervalSince1970: 1_700_000_000)
        var entries: [PlanUtilizationHistoryEntry] = []

        for offset in 0..<maxSamples {
            entries.append(planEntry(
                at: base.addingTimeInterval(Double(offset) * 3600),
                usedPercent: Double(offset % 100)))
        }

        let appended = planEntry(
            at: base.addingTimeInterval(Double(maxSamples) * 3600),
            usedPercent: 50)

        let updated = try #require(
            UsageStore._updatedPlanUtilizationEntriesForTesting(
                existingEntries: entries,
                entry: appended))

        #expect(updated.count == maxSamples)
        #expect(updated.first?.capturedAt == entries[1].capturedAt)
        #expect(updated.last == appended)
    }

    @MainActor
    @Test
    func `native chart shows visible series tabs only`() {
        let histories = [
            planSeries(name: .session, windowMinutes: 0, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 90),
            ]),
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 20),
            ]),
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 48),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .codex)

        #expect(model.visibleSeries == ["session:300", "weekly:10080"])
        #expect(model.selectedSeries == "session:300")
    }

    @MainActor
    @Test
    func `native chart folds near canonical codex windows into single tabs`() {
        let histories = [
            planSeries(name: .session, windowMinutes: 299, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 20),
            ]),
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_003_600), usedPercent: 30),
            ]),
            planSeries(name: .weekly, windowMinutes: 10079, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 40),
            ]),
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_172_800), usedPercent: 50),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .codex)

        #expect(model.visibleSeries == ["session:300", "weekly:10080"])
        #expect(model.selectedSeries == "session:300")
    }

    @MainActor
    @Test
    func `native chart shows monthly codex tab for a thirty day primary`() {
        let histories = [
            planSeries(name: .monthly, windowMinutes: 43200, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 55),
            ]),
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 5),
            ]),
        ]
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 55, windowMinutes: 43200, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 5, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(timeIntervalSince1970: 1_700_000_000))

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .codex,
            snapshot: snapshot)

        #expect(model.visibleSeries == ["weekly:10080", "monthly:43200"])
        #expect(model.selectedSeries == "weekly:10080")
    }

    @MainActor
    @Test
    func `native chart folds legacy thirty day session and weekly history into monthly`() {
        let histories = [
            planSeries(name: .session, windowMinutes: 43200, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 80),
            ]),
            planSeries(name: .weekly, windowMinutes: 43200, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 70),
            ]),
            planSeries(name: .monthly, windowMinutes: 43200, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_172_800), usedPercent: 55),
            ]),
        ]
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 55, windowMinutes: 43200, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 5, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(timeIntervalSince1970: 1_700_000_000))

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .codex,
            snapshot: snapshot)

        #expect(model.visibleSeries == ["monthly:43200"])
        #expect(model.selectedSeries == "monthly:43200")
    }

    @MainActor
    @Test
    func `claude history tabs match current snapshot bars`() {
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 20),
            ]),
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 48),
            ]),
            planSeries(name: .opus, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 12),
            ]),
        ]
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 3, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 10, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            tertiary: nil,
            updatedAt: Date(timeIntervalSince1970: 1_700_086_400),
            identity: nil)

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .claude,
            snapshot: snapshot)

        #expect(model.visibleSeries == ["session:300", "weekly:10080"])
        #expect(model.selectedSeries == "session:300")
    }

    @MainActor
    @Test
    func `opencodego history tabs include the monthly series`() {
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 12),
            ]),
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 57),
            ]),
            planSeries(name: .monthly, windowMinutes: 43200, entries: [
                planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 34),
            ]),
        ]
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 12, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 57, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            tertiary: RateWindow(usedPercent: 34, windowMinutes: 43200, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(timeIntervalSince1970: 1_700_086_400),
            identity: nil)

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            histories: histories,
            provider: .opencodego,
            snapshot: snapshot)

        #expect(model.visibleSeries == ["session:300", "weekly:10080", "monthly:43200"])
        #expect(model.selectedSeries == "session:300")
    }

    @MainActor
    @Test
    func `session chart uses native reset boundaries and fills missing windows`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let firstBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 4,
            hour: 10)))
        let thirdBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 4,
            hour: 20)))
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: firstBoundary.addingTimeInterval(-30 * 60), usedPercent: 62, resetsAt: firstBoundary),
                planEntry(at: thirdBoundary.addingTimeInterval(-30 * 60), usedPercent: 20, resetsAt: thirdBoundary),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: thirdBoundary)

        #expect(model.pointCount == 3)
        #expect(model.usedPercents == [62, 0, 20])
        #expect(model.pointDates == [
            formattedBoundary(firstBoundary),
            formattedBoundary(firstBoundary.addingTimeInterval(5 * 60 * 60)),
            formattedBoundary(thirdBoundary),
        ])
    }

    @MainActor
    @Test
    func `session chart labels only day changes`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let firstBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 4,
            hour: 20)))
        let thirdBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 5,
            hour: 6)))
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: firstBoundary.addingTimeInterval(-30 * 60), usedPercent: 62, resetsAt: firstBoundary),
                planEntry(at: thirdBoundary.addingTimeInterval(-30 * 60), usedPercent: 20, resetsAt: thirdBoundary),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: thirdBoundary)

        #expect(model.axisIndexes == [0])
    }

    @MainActor
    @Test
    func `session chart labels every second day change`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let firstBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 4,
            hour: 20)))
        let secondBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 5,
            hour: 6)))
        let thirdBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 6,
            hour: 6)))
        let fourthBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 7,
            hour: 6)))
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: firstBoundary.addingTimeInterval(-30 * 60), usedPercent: 62, resetsAt: firstBoundary),
                planEntry(at: secondBoundary.addingTimeInterval(-30 * 60), usedPercent: 20, resetsAt: secondBoundary),
                planEntry(at: thirdBoundary.addingTimeInterval(-30 * 60), usedPercent: 35, resetsAt: thirdBoundary),
                planEntry(at: fourthBoundary.addingTimeInterval(-30 * 60), usedPercent: 18, resetsAt: fourthBoundary),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: fourthBoundary)

        #expect(model.axisIndexes == [0])
    }

    @MainActor
    @Test
    func `session chart drops trailing day label when it would clip at chart edge`() throws {
        let calendar = Calendar(identifier: .gregorian)
        let firstBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 4,
            hour: 20)))
        let secondBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 5,
            hour: 6)))
        let thirdBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 6,
            hour: 6)))
        let fourthBoundary = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone.current,
            year: 2026,
            month: 3,
            day: 7,
            hour: 20)))
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: firstBoundary.addingTimeInterval(-30 * 60), usedPercent: 62, resetsAt: firstBoundary),
                planEntry(at: secondBoundary.addingTimeInterval(-30 * 60), usedPercent: 20, resetsAt: secondBoundary),
                planEntry(at: thirdBoundary.addingTimeInterval(-30 * 60), usedPercent: 35, resetsAt: thirdBoundary),
                planEntry(at: fourthBoundary.addingTimeInterval(-30 * 60), usedPercent: 18, resetsAt: fourthBoundary),
            ]),
        ]

        let model = PlanUtilizationHistoryChartMenuView._modelSnapshotForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: fourthBoundary)

        #expect(model.axisIndexes == [0, 10])
    }

    @MainActor
    @Test
    func `detail line shows used and wasted without provenance copy`() {
        let boundary = Date(timeIntervalSince1970: 1_710_000_000)
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: boundary.addingTimeInterval(-30 * 60), usedPercent: 48, resetsAt: boundary),
            ]),
        ]

        let detail = PlanUtilizationHistoryChartMenuView._detailLineForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: boundary.addingTimeInterval(-1))

        #expect(detail.contains("48% used"))
        #expect(!detail.contains("Provider-reported"))
        #expect(!detail.contains("Estimated"))
        #expect(!detail.contains("wasted"))
    }

    @MainActor
    @Test
    func `detail line shows dash for missing window`() {
        let boundary = Date(timeIntervalSince1970: 1_710_000_000)
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: boundary.addingTimeInterval(-30 * 60), usedPercent: 48, resetsAt: boundary),
            ]),
        ]

        let detail = PlanUtilizationHistoryChartMenuView._detailLineForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: boundary.addingTimeInterval(5 * 60 * 60))

        #expect(detail.contains(": -"))
    }

    @MainActor
    @Test
    func `detail line keeps zero percent for observed zero usage`() {
        let boundary = Date(timeIntervalSince1970: 1_710_000_000)
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: boundary.addingTimeInterval(-30 * 60), usedPercent: 0, resetsAt: boundary),
            ]),
        ]

        let detail = PlanUtilizationHistoryChartMenuView._detailLineForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: boundary.addingTimeInterval(-1))

        #expect(detail.contains("0% used"))
        #expect(!detail.contains(": -"))
    }

    @MainActor
    @Test
    func `detail line uses lowercase am pm for session hover`() {
        let previousLanguage = UserDefaults.standard.object(forKey: "appLanguage")
        UserDefaults.standard.set("en", forKey: "appLanguage")
        defer {
            if let previousLanguage {
                UserDefaults.standard.set(previousLanguage, forKey: "appLanguage")
            } else {
                UserDefaults.standard.removeObject(forKey: "appLanguage")
            }
        }

        let boundary = Date(timeIntervalSince1970: 1_710_048_000) // Mar 11, 2024 1:20 pm UTC
        let histories = [
            planSeries(name: .session, windowMinutes: 300, entries: [
                planEntry(at: boundary.addingTimeInterval(-30 * 60), usedPercent: 48, resetsAt: boundary),
            ]),
        ]

        let detail = PlanUtilizationHistoryChartMenuView._detailLineForTesting(
            selectedSeriesRawValue: "session:300",
            histories: histories,
            provider: .codex,
            referenceDate: boundary.addingTimeInterval(-1))

        #expect(detail.contains(" am") || detail.contains(" pm"))
        #expect(!detail.contains("PM"))
        #expect(!detail.contains("AM"))
    }

    @MainActor
    @Test
    func `detail line uses lowercase am pm for weekly hover`() {
        let previousLanguage = UserDefaults.standard.object(forKey: "appLanguage")
        UserDefaults.standard.set("en", forKey: "appLanguage")
        defer {
            if let previousLanguage {
                UserDefaults.standard.set(previousLanguage, forKey: "appLanguage")
            } else {
                UserDefaults.standard.removeObject(forKey: "appLanguage")
            }
        }

        let boundary = Date(timeIntervalSince1970: 1_710_048_000) // Mar 11, 2024 1:20 pm UTC
        let histories = [
            planSeries(name: .weekly, windowMinutes: 10080, entries: [
                planEntry(at: boundary.addingTimeInterval(-30 * 60), usedPercent: 48, resetsAt: boundary),
            ]),
        ]

        let detail = PlanUtilizationHistoryChartMenuView._detailLineForTesting(
            selectedSeriesRawValue: "weekly:10080",
            histories: histories,
            provider: .codex,
            referenceDate: boundary.addingTimeInterval(-1))

        #expect(detail.contains(" am") || detail.contains(" pm"))
        #expect(!detail.contains("PM"))
        #expect(!detail.contains("AM"))
    }

    @Test
    func `chart empty state shows series specific message`() {
        let text = PlanUtilizationHistoryChartMenuView._emptyStateTextForTesting(title: "Session")
        #expect(text == "No session utilization data yet.")
    }

    @Test
    func `chart empty state shows series specific message when not refreshing`() {
        let text = PlanUtilizationHistoryChartMenuView._emptyStateTextForTesting(title: "Weekly")
        #expect(text == "No weekly utilization data yet.")
    }

    @MainActor
    @Test
    func `plan history records thirty day codex window as monthly series`() async {
        let store = Self.makeStore()
        let now = Date(timeIntervalSince1970: 1_800_000_000)
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 55,
                windowMinutes: 43200,
                resetsAt: now.addingTimeInterval(24 * 86400),
                resetDescription: nil),
            secondary: RateWindow(
                usedPercent: 5,
                windowMinutes: 10080,
                resetsAt: now.addingTimeInterval(7 * 86400),
                resetDescription: nil),
            updatedAt: now,
            identity: ProviderIdentitySnapshot(
                providerID: .codex,
                accountEmail: "codex@example.com",
                accountOrganization: nil,
                loginMethod: "plus"))
        store._setSnapshotForTesting(snapshot, provider: .codex)

        await store.recordPlanUtilizationHistorySample(
            provider: .codex,
            snapshot: snapshot,
            now: now)

        let histories = store.planUtilizationHistory(for: .codex)
        #expect(histories.contains { $0.name == .monthly && $0.windowMinutes == 43200 })
        #expect(histories.contains { $0.name == .weekly && $0.windowMinutes == 10080 })
        #expect(!histories.contains { $0.name == .session })
    }

    @MainActor
    @Test
    func `plan history selects current account bucket`() throws {
        let store = Self.makeStore()
        let aliceSnapshot = Self.makeSnapshot(provider: .codex, email: "alice@example.com")
        let bobSnapshot = Self.makeSnapshot(provider: .codex, email: "bob@example.com")
        let aliceKey = try #require(
            UsageStore._planUtilizationAccountKeyForTesting(
                provider: .codex,
                snapshot: aliceSnapshot))
        let bobKey = try #require(
            UsageStore._planUtilizationAccountKeyForTesting(
                provider: .codex,
                snapshot: bobSnapshot))

        let bootstrap = planSeries(name: .session, windowMinutes: 300, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_699_913_600), usedPercent: 90),
        ])
        let aliceWeekly = planSeries(name: .weekly, windowMinutes: 10080, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 20),
        ])
        let bobWeekly = planSeries(name: .weekly, windowMinutes: 10080, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 50),
        ])

        store.planUtilizationHistory[.codex] = PlanUtilizationHistoryBuckets(
            unscoped: [bootstrap],
            accounts: [
                aliceKey: [aliceWeekly],
                bobKey: [bobWeekly],
            ])

        store._setSnapshotForTesting(aliceSnapshot, provider: .codex)
        let aliceHistory = store.planUtilizationHistory(for: .codex)
        #expect(store.planUtilizationHistory[.codex]?.preferredAccountKey == aliceKey)
        #expect(aliceHistory == [aliceWeekly])
        #expect(store.planUtilizationHistory[.codex]?.unscoped == [bootstrap])

        store._setSnapshotForTesting(bobSnapshot, provider: .codex)
        let bobHistory = store.planUtilizationHistory(for: .codex)
        #expect(store.planUtilizationHistory[.codex]?.preferredAccountKey == bobKey)
        #expect(bobHistory == [bobWeekly])
    }

    @MainActor
    @Test
    func `cursor automatic history ignores dormant saved token account`() async throws {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        store.settings.addTokenAccount(
            provider: .cursor,
            label: "Dormant manual account",
            token: "fixture")
        let dormantAccount = try #require(store.settings.selectedTokenAccount(for: .cursor))
        let dormantAccountKey = try #require(
            UsageStore._planUtilizationTokenAccountKeyForTesting(
                provider: .cursor,
                account: dormantAccount))
        store.settings.cursorCookieSource = .auto

        let browserSnapshot = Self.makeSnapshot(provider: .cursor, email: "browser@example.com")
        let browserAccountKey = try #require(
            UsageStore._planUtilizationAccountKeyForTesting(
                provider: .cursor,
                snapshot: browserSnapshot))
        store._setSnapshotForTesting(browserSnapshot, provider: .cursor)

        await store.recordPlanUtilizationHistorySample(
            provider: .cursor,
            snapshot: browserSnapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .cursor)
        let buckets = try #require(store.planUtilizationHistory[.cursor])
        #expect(store.settings.selectedTokenAccount(for: .cursor)?.id == dormantAccount.id)
        #expect(store.settings.effectiveSelectedTokenAccount(for: .cursor) == nil)
        #expect(buckets.preferredAccountKey == browserAccountKey)
        #expect(buckets.accounts[dormantAccountKey] == nil)
        #expect(histories == buckets.accounts[browserAccountKey])
        #expect(!histories.isEmpty)
    }

    @MainActor
    @Test
    func `plan utilization menu hides while refreshing without current snapshot`() throws {
        let store = Self.makeStore()
        let claudeKey = try #require(
            UsageStore._planUtilizationAccountKeyForTesting(
                provider: .claude,
                snapshot: Self.makeSnapshot(provider: .claude, email: "alice@example.com")))
        let weekly = planSeries(name: .weekly, windowMinutes: 10080, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 64),
        ])
        store.planUtilizationHistory[.claude] = PlanUtilizationHistoryBuckets(
            preferredAccountKey: claudeKey,
            accounts: [
                claudeKey: [weekly],
            ])
        store.refreshingProviders.insert(.claude)
        store._setSnapshotForTesting(nil, provider: .claude)

        #expect(store.shouldShowRefreshingMenuCard(for: .claude))
        #expect(store.shouldHidePlanUtilizationMenuItem(for: .claude))
    }

    @MainActor
    @Test
    func `plan utilization menu stays visible with stored snapshot even during refresh`() throws {
        let store = Self.makeStore()
        let codexSnapshot = Self.makeSnapshot(provider: .codex, email: "alice@example.com")
        let codexKey = try #require(
            UsageStore._planUtilizationAccountKeyForTesting(
                provider: .codex,
                snapshot: codexSnapshot))
        let weekly = planSeries(name: .weekly, windowMinutes: 10080, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 64),
        ])
        store.planUtilizationHistory[.codex] = PlanUtilizationHistoryBuckets(
            preferredAccountKey: codexKey,
            accounts: [
                codexKey: [weekly],
            ])
        store.refreshingProviders.insert(.codex)
        store._setSnapshotForTesting(codexSnapshot, provider: .codex)

        #expect(!store.shouldShowRefreshingMenuCard(for: .codex))
        #expect(!store.shouldHidePlanUtilizationMenuItem(for: .codex))
        let histories = store.planUtilizationHistory(for: .codex)
        #expect(store.planUtilizationHistory[.codex]?.preferredAccountKey == codexKey)
        #expect(histories == [weekly])
    }

    @MainActor
    @Test
    func `codex plan utilization menu hides during provider only refresh without snapshot`() {
        let store = Self.makeStore()
        store.refreshingProviders.insert(.codex)
        store._setSnapshotForTesting(nil, provider: .codex)

        #expect(store.shouldShowRefreshingMenuCard(for: .codex))
        #expect(store.shouldHidePlanUtilizationMenuItem(for: .codex))
    }

    @MainActor
    @Test
    func `record plan history persists named series from snapshot`() async {
        let store = Self.makeStore()
        let primaryReset = Date(timeIntervalSince1970: 1_710_000_000)
        let secondaryReset = Date(timeIntervalSince1970: 1_710_086_400)
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 110,
                windowMinutes: 300,
                resetsAt: primaryReset,
                resetDescription: "5h"),
            secondary: RateWindow(
                usedPercent: -20,
                windowMinutes: 10080,
                resetsAt: secondaryReset,
                resetDescription: "7d"),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: .codex,
                accountEmail: "alice@example.com",
                accountOrganization: nil,
                loginMethod: "plus"))
        store._setSnapshotForTesting(snapshot, provider: .codex)

        await store.recordPlanUtilizationHistorySample(
            provider: .codex,
            snapshot: snapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .codex)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.last?.usedPercent == 100)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.last?.resetsAt == primaryReset)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.usedPercent == 0)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.resetsAt == secondaryReset)
    }

    @MainActor
    @Test
    func `record plan history skips invalid zero minute windows`() async {
        let store = Self.makeStore()
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 25,
                windowMinutes: 0,
                resetsAt: Date(timeIntervalSince1970: 1_710_000_000),
                resetDescription: nil),
            secondary: RateWindow(
                usedPercent: 44,
                windowMinutes: 10080,
                resetsAt: Date(timeIntervalSince1970: 1_710_086_400),
                resetDescription: nil),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: .codex,
                accountEmail: "alice@example.com",
                accountOrganization: nil,
                loginMethod: "plus"))
        store._setSnapshotForTesting(snapshot, provider: .codex)

        await store.recordPlanUtilizationHistorySample(
            provider: .codex,
            snapshot: snapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .codex)
        #expect(findSeries(histories, name: .session, windowMinutes: 0) == nil)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.usedPercent == 44)
    }

    @MainActor
    @Test
    func `record plan history keeps semantic codex lanes when durations drift`() async {
        let store = Self.makeStore()
        let primaryReset = Date(timeIntervalSince1970: 1_710_000_000)
        let secondaryReset = Date(timeIntervalSince1970: 1_710_086_400)
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 18,
                windowMinutes: 360,
                resetsAt: primaryReset,
                resetDescription: "6h"),
            secondary: RateWindow(
                usedPercent: 42,
                windowMinutes: 11040,
                resetsAt: secondaryReset,
                resetDescription: "7.67d"),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: .codex,
                accountEmail: "alice@example.com",
                accountOrganization: nil,
                loginMethod: "plus"))
        store._setSnapshotForTesting(snapshot, provider: .codex)

        await store.recordPlanUtilizationHistorySample(
            provider: .codex,
            snapshot: snapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .codex)
        #expect(findSeries(histories, name: .session, windowMinutes: 360)?.entries.last?.usedPercent == 18)
        #expect(findSeries(histories, name: .session, windowMinutes: 360)?.entries.last?.resetsAt == primaryReset)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 11040)?.entries.last?.usedPercent == 42)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 11040)?.entries.last?.resetsAt == secondaryReset)
    }

    @MainActor
    @Test
    func `record plan history stores claude opus as separate series`() async {
        let store = Self.makeStore()
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 10, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 20, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            tertiary: RateWindow(usedPercent: 30, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: .claude,
                accountEmail: "alice@example.com",
                accountOrganization: nil,
                loginMethod: "max"))
        store._setSnapshotForTesting(snapshot, provider: .claude)

        await store.recordPlanUtilizationHistorySample(
            provider: .claude,
            snapshot: snapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .claude)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.last?.usedPercent == 10)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.usedPercent == 20)
        #expect(findSeries(histories, name: .opus, windowMinutes: 10080)?.entries.last?.usedPercent == 30)
    }

    @MainActor
    @Test
    func `opencodego plan history is always supported like codex and claude`() {
        let store = Self.makeStore()
        #expect(store.settings.historicalTrackingEnabled == false)
        #expect(store.supportsPlanUtilizationHistory(for: .opencodego))
    }

    @MainActor
    @Test
    func `record plan history stores opencodego monthly series`() async {
        let store = Self.makeStore()
        // historicalTrackingEnabled defaults to false; opencodego must still record, like codex/claude.
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 12, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 57, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            tertiary: RateWindow(usedPercent: 34, windowMinutes: 43200, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: .opencodego,
                accountEmail: nil,
                accountOrganization: nil,
                loginMethod: nil))
        store._setSnapshotForTesting(snapshot, provider: .opencodego)

        await store.recordPlanUtilizationHistorySample(
            provider: .opencodego,
            snapshot: snapshot,
            now: Date(timeIntervalSince1970: 1_700_000_000))

        let histories = store.planUtilizationHistory(for: .opencodego)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.last?.usedPercent == 12)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.usedPercent == 57)
        #expect(findSeries(histories, name: .monthly, windowMinutes: 43200)?.entries.last?.usedPercent == 34)
    }

    @MainActor
    @Test
    func `record plan history stores mimo monthly series`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 34,
                windowMinutes: ProviderPaceCapability.monthlyWindowSentinelMinutes,
                resetsAt: now.addingTimeInterval(20 * 24 * 60 * 60),
                resetDescription: nil),
            secondary: nil,
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .mimo, snapshot: snapshot, now: now)

        let histories = store.planUtilizationHistory(for: .mimo)
        #expect(findSeries(histories, name: .monthly, windowMinutes: 43200)?.entries.last?.usedPercent == 34)
    }

    @MainActor
    @Test
    func `record plan history stores stepfun monthly series`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: RateWindow(
                usedPercent: 58,
                windowMinutes: ProviderPaceCapability.monthlyWindowSentinelMinutes,
                resetsAt: now.addingTimeInterval(20 * 24 * 60 * 60),
                resetDescription: nil),
            secondary: nil,
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .stepfun, snapshot: snapshot, now: now)

        let histories = store.planUtilizationHistory(for: .stepfun)
        #expect(findSeries(histories, name: .monthly, windowMinutes: 43200)?.entries.last?.usedPercent == 58)
    }

    @MainActor
    @Test
    func `stepfun rolling windows keep their session and weekly history lanes`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: RateWindow(usedPercent: 25, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 40, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .stepfun, snapshot: snapshot, now: now)

        let histories = store.planUtilizationHistory(for: .stepfun)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.last?.usedPercent == 25)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.last?.usedPercent == 40)
    }

    @MainActor
    @Test
    func `generic provider weekly lane is persisted to provider history json`() async throws {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let accountLabel = "zai-history-org"
        let firstDate = Date(timeIntervalSince1970: 1_700_000_000)
        let before = UsageSnapshot(
            primary: RateWindow(usedPercent: 42, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 15, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            updatedAt: firstDate,
            identity: ProviderIdentitySnapshot(
                providerID: .zai,
                accountEmail: nil,
                accountOrganization: accountLabel,
                loginMethod: "pro"))
        let after = UsageSnapshot(
            primary: RateWindow(usedPercent: 58, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 25, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            updatedAt: firstDate.addingTimeInterval(3600),
            identity: ProviderIdentitySnapshot(
                providerID: .zai,
                accountEmail: nil,
                accountOrganization: accountLabel,
                loginMethod: "pro"))

        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: before, now: before.updatedAt)
        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: after, now: after.updatedAt)

        let histories = store.planUtilizationHistory(for: .zai)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.map(\.usedPercent) == [42, 58])
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.map(\.usedPercent) == [15, 25])

        let providerURL = try #require(store.planUtilizationHistoryStore.directoryURL?
            .appendingPathComponent("zai.json", isDirectory: false))
        var persistedBuckets: PlanUtilizationHistoryBuckets?
        for _ in 0..<20 {
            persistedBuckets = store.planUtilizationHistoryStore.load()[.zai]
            let weeklyEntries = persistedBuckets?.histories(for: persistedBuckets?.preferredAccountKey)
                .first { $0.name == .weekly }?.entries.count
            if weeklyEntries == 2 {
                break
            }
            try await Task.sleep(nanoseconds: 50_000_000)
        }
        #expect(FileManager.default.fileExists(atPath: providerURL.path))
        let persisted = try #require(persistedBuckets)
        #expect(persisted.histories(for: persisted.preferredAccountKey)
            .first { $0.name == .weekly }?.entries.map(\.usedPercent) == [42, 58])
    }

    @MainActor
    @Test
    func `generic history opt in controls recording while saved history stays visible`() async throws {
        let store = Self.makeStore()
        let firstDate = Date(timeIntervalSince1970: 1_700_000_000)
        let before = UsageSnapshot(
            primary: RateWindow(usedPercent: 42, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            secondary: nil,
            updatedAt: firstDate)
        store._setSnapshotForTesting(before, provider: .zai)
        let providerURL = try #require(store.planUtilizationHistoryStore.directoryURL?
            .appendingPathComponent("zai.json", isDirectory: false))

        #expect(store.settings.historicalTrackingEnabled == false)
        #expect(store.supportsPlanUtilizationHistory(for: .zai) == false)
        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: before, now: before.updatedAt)
        #expect(store.planUtilizationHistory(for: .zai).isEmpty)
        #expect(FileManager.default.fileExists(atPath: providerURL.path) == false)

        store.settings.historicalTrackingEnabled = true
        #expect(store.supportsPlanUtilizationHistory(for: .zai))
        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: before, now: before.updatedAt)
        #expect(findSeries(store.planUtilizationHistory(for: .zai), name: .weekly, windowMinutes: 10080)?
            .entries.map(\.usedPercent) == [42])

        store.settings.historicalTrackingEnabled = false
        #expect(store.supportsPlanUtilizationHistory(for: .zai))
        let after = UsageSnapshot(
            primary: RateWindow(usedPercent: 58, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            secondary: nil,
            updatedAt: firstDate.addingTimeInterval(3600))
        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: after, now: after.updatedAt)
        #expect(findSeries(store.planUtilizationHistory(for: .zai), name: .weekly, windowMinutes: 10080)?
            .entries.map(\.usedPercent) == [42])

        for _ in 0..<20 where !FileManager.default.fileExists(atPath: providerURL.path) {
            try await Task.sleep(nanoseconds: 50_000_000)
        }
        #expect(FileManager.default.fileExists(atPath: providerURL.path))
    }

    @MainActor
    @Test
    func `generic provider persists weekly extra window`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: nil,
            secondary: nil,
            extraRateWindows: [
                NamedRateWindow(
                    id: "weekly-budget",
                    title: "Weekly budget",
                    window: RateWindow(
                        usedPercent: 42,
                        windowMinutes: 10080,
                        resetsAt: nil,
                        resetDescription: nil)),
            ],
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .zai, snapshot: snapshot, now: now)

        #expect(findSeries(store.planUtilizationHistory(for: .zai), name: .weekly, windowMinutes: 10080)?
            .entries.map(\.usedPercent) == [42])
    }

    @MainActor
    @Test
    func `generic provider ignores unknown weekly extra window`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: nil,
            secondary: nil,
            extraRateWindows: [
                NamedRateWindow(
                    id: "weekly-reset-only",
                    title: "Weekly reset",
                    window: RateWindow(
                        usedPercent: 0,
                        windowMinutes: 10080,
                        resetsAt: now.addingTimeInterval(3600),
                        resetDescription: nil),
                    usageKnown: false),
            ],
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .zed, snapshot: snapshot, now: now)

        #expect(store.planUtilizationHistory(for: .zed).isEmpty)
    }

    @MainActor
    @Test
    func `generic provider prefers standard weekly window over extra window`() async {
        let store = Self.makeStore()
        store.settings.historicalTrackingEnabled = true
        let now = Date(timeIntervalSince1970: 1_700_000_000)
        let snapshot = UsageSnapshot(
            primary: nil,
            secondary: RateWindow(
                usedPercent: 42,
                windowMinutes: 10080,
                resetsAt: nil,
                resetDescription: nil),
            extraRateWindows: [
                NamedRateWindow(
                    id: "extra-weekly-budget",
                    title: "Extra weekly budget",
                    window: RateWindow(
                        usedPercent: 84,
                        windowMinutes: 10080,
                        resetsAt: nil,
                        resetDescription: nil)),
            ],
            updatedAt: now)

        await store.recordPlanUtilizationHistorySample(provider: .factory, snapshot: snapshot, now: now)

        #expect(findSeries(store.planUtilizationHistory(for: .factory), name: .weekly, windowMinutes: 10080)?
            .entries.map(\.usedPercent) == [42])
    }

    @MainActor
    @Test
    func `concurrent plan history writes coalesce within single hour bucket per series`() async throws {
        let store = Self.makeStore()
        let snapshot = Self.makeSnapshot(provider: .codex, email: "alice@example.com")
        store._setSnapshotForTesting(snapshot, provider: .codex)
        let calendar = Calendar(identifier: .gregorian)
        let hourStart = try #require(calendar.date(from: DateComponents(
            timeZone: TimeZone(secondsFromGMT: 0),
            year: 2026,
            month: 3,
            day: 17,
            hour: 10)))
        let writeTimes = [
            hourStart.addingTimeInterval(5 * 60),
            hourStart.addingTimeInterval(25 * 60),
            hourStart.addingTimeInterval(45 * 60),
        ]

        await withTaskGroup(of: Void.self) { group in
            for writeTime in writeTimes {
                group.addTask {
                    await store.recordPlanUtilizationHistorySample(
                        provider: .codex,
                        snapshot: snapshot,
                        now: writeTime)
                }
            }
        }

        let histories = try #require(store.planUtilizationHistory[.codex]?.accounts.values.first)
        #expect(findSeries(histories, name: .session, windowMinutes: 300)?.entries.count == 1)
        #expect(findSeries(histories, name: .weekly, windowMinutes: 10080)?.entries.count == 1)
    }

    @Test
    func `runtime does not load unsupported plan history file`() throws {
        let root = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString, isDirectory: true)
        let directoryURL = root
            .appendingPathComponent("com.steipete.codexbar", isDirectory: true)
            .appendingPathComponent("history", isDirectory: true)
        let providerURL = directoryURL.appendingPathComponent("codex.json")
        let store = PlanUtilizationHistoryStore(directoryURL: directoryURL)
        try FileManager.default.createDirectory(
            at: directoryURL,
            withIntermediateDirectories: true)

        let unsupportedJSON = """
        {
          "version": 999,
          "unscoped": [],
          "accounts": {}
        }
        """
        try Data(unsupportedJSON.utf8).write(to: providerURL, options: Data.WritingOptions.atomic)

        let loaded = store.load()
        #expect(loaded.isEmpty)
    }

    @Test
    func `store drops invalid zero minute and empty histories when loading and saving`() throws {
        let root = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString, isDirectory: true)
        let directoryURL = root
            .appendingPathComponent("com.steipete.codexbar", isDirectory: true)
            .appendingPathComponent("history", isDirectory: true)
        let providerURL = directoryURL.appendingPathComponent("codex.json")
        let store = PlanUtilizationHistoryStore(directoryURL: directoryURL)
        try FileManager.default.createDirectory(
            at: directoryURL,
            withIntermediateDirectories: true)

        let validUnscoped = planSeries(name: .session, windowMinutes: 300, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 12),
        ])
        let validAccount = planSeries(name: .weekly, windowMinutes: 10080, entries: [
            planEntry(at: Date(timeIntervalSince1970: 1_700_086_400), usedPercent: 64),
        ])
        let document = PersistedFixtureDocument(
            version: 1,
            preferredAccountKey: "alice",
            unscoped: [
                planSeries(name: .session, windowMinutes: 0, entries: [
                    planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 99),
                ]),
                planSeries(name: .weekly, windowMinutes: 10080, entries: []),
                validUnscoped,
            ],
            accounts: [
                "alice": [
                    planSeries(name: .session, windowMinutes: 0, entries: [
                        planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 88),
                    ]),
                    validAccount,
                ],
                "empty": [
                    planSeries(name: .weekly, windowMinutes: 10080, entries: []),
                ],
            ])
        let encoder = JSONEncoder()
        encoder.dateEncodingStrategy = .iso8601
        try encoder.encode(document).write(to: providerURL, options: Data.WritingOptions.atomic)

        let loaded = store.load()
        let loadedBuckets = try #require(loaded[.codex])
        #expect(loadedBuckets.unscoped == [validUnscoped])
        #expect(loadedBuckets.accounts == ["alice": [validAccount]])

        store.save(loaded)

        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        let rewritten = try decoder.decode(PersistedFixtureDocument.self, from: Data(contentsOf: providerURL))
        #expect(rewritten.unscoped == [validUnscoped])
        #expect(rewritten.accounts == ["alice": [validAccount]])
    }

    @Test
    func `store round trips account buckets with series entries`() {
        let root = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString, isDirectory: true)
        let directoryURL = root
            .appendingPathComponent("com.steipete.codexbar", isDirectory: true)
            .appendingPathComponent("history", isDirectory: true)
        let store = PlanUtilizationHistoryStore(directoryURL: directoryURL)
        var buckets = PlanUtilizationHistoryBuckets(
            preferredAccountKey: "alice",
            unscoped: [
                planSeries(name: .session, windowMinutes: 300, entries: [
                    planEntry(at: Date(timeIntervalSince1970: 1_699_913_600), usedPercent: 50),
                ]),
            ],
            accounts: [
                "alice": [
                    planSeries(name: .session, windowMinutes: 300, entries: [
                        planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 10),
                    ]),
                    planSeries(name: .weekly, windowMinutes: 10080, entries: [
                        planEntry(at: Date(timeIntervalSince1970: 1_700_000_000), usedPercent: 20),
                    ]),
                ],
            ])
        buckets.setSessionEquivalentWindowPairIdentity("session:standard|weekly:standard", for: "alice")

        store.save([.codex: buckets])
        let loaded = store.load()

        #expect(loaded == [.codex: buckets])
    }

    @Test
    func `store persists an invalidated pair identity without histories`() {
        let root = FileManager.default.temporaryDirectory
            .appendingPathComponent(UUID().uuidString, isDirectory: true)
        let directoryURL = root
            .appendingPathComponent("com.steipete.codexbar", isDirectory: true)
            .appendingPathComponent("history", isDirectory: true)
        let store = PlanUtilizationHistoryStore(directoryURL: directoryURL)
        var buckets = PlanUtilizationHistoryBuckets()
        buckets.invalidateSessionEquivalentWindowPairIdentity(for: nil)

        store.save([.zai: buckets])

        #expect(store.load() == [.zai: buckets])
    }
}

extension UsageStorePlanUtilizationTests {
    private struct PersistedFixtureDocument: Codable {
        let version: Int
        let preferredAccountKey: String?
        let unscoped: [PlanUtilizationSeriesHistory]
        let accounts: [String: [PlanUtilizationSeriesHistory]]
    }

    private struct FixtureDocument: Decodable {
        let preferredAccountKey: String?
        let unscoped: [PlanUtilizationSeriesHistory]
        let accounts: [String: [PlanUtilizationSeriesHistory]]
    }

    @MainActor
    static func makeStore() -> UsageStore {
        let suiteName = "UsageStorePlanUtilizationTests-\(UUID().uuidString)"
        guard let defaults = UserDefaults(suiteName: suiteName) else {
            fatalError("Failed to create isolated UserDefaults suite for tests")
        }
        defaults.removePersistentDomain(forName: suiteName)
        let configStore = testConfigStore(suiteName: suiteName)
        let planHistoryStore = testPlanUtilizationHistoryStore(suiteName: suiteName)
        let temporaryRoot = FileManager.default.temporaryDirectory.standardizedFileURL.path
        let managedStoreURL = FileManager.default.temporaryDirectory
            .appendingPathComponent("\(suiteName)-managed-codex-accounts.json")
        precondition(configStore.fileURL.standardizedFileURL.path.hasPrefix(temporaryRoot))
        precondition(configStore.fileURL.standardizedFileURL != CodexBarConfigStore.defaultURL().standardizedFileURL)
        if let historyURL = planHistoryStore.directoryURL?.standardizedFileURL {
            precondition(historyURL.path.hasPrefix(temporaryRoot))
        }
        let managedStore = FileManagedCodexAccountStore(fileURL: managedStoreURL)
        try? FileManager.default.removeItem(at: managedStoreURL)
        do {
            try managedStore.storeAccounts(ManagedCodexAccountSet(
                version: FileManagedCodexAccountStore.currentVersion,
                accounts: []))
        } catch {
            fatalError("Failed to seed isolated managed Codex account store: \(error)")
        }
        let isolatedSettings = SettingsStore(
            userDefaults: defaults,
            configStore: configStore,
            tokenAccountStore: InMemoryTokenAccountStore())
        let store = UsageStore(
            fetcher: UsageFetcher(),
            browserDetection: BrowserDetection(cacheTTL: 0),
            settings: isolatedSettings,
            planUtilizationHistoryStore: planHistoryStore,
            startupBehavior: .testing)
        isolatedSettings._test_managedCodexAccountStoreURL = managedStoreURL
        isolatedSettings.codexActiveSource = .liveSystem
        // Cancel the background plan-utilization decode so it cannot race the
        // explicit empty assignment below. Production paths still load on the
        // utility queue; this only short-circuits the test setup.
        store._cancelPlanUtilizationHistoryLoadForTesting()
        store.planUtilizationHistory = [:]
        return store
    }

    static func makeSnapshot(provider: UsageProvider, email: String) -> UsageSnapshot {
        UsageSnapshot(
            primary: RateWindow(usedPercent: 10, windowMinutes: 300, resetsAt: nil, resetDescription: nil),
            secondary: RateWindow(usedPercent: 20, windowMinutes: 10080, resetsAt: nil, resetDescription: nil),
            updatedAt: Date(),
            identity: ProviderIdentitySnapshot(
                providerID: provider.instanceID,
                accountEmail: email,
                accountOrganization: nil,
                loginMethod: "plus"))
    }

    static func loadPlanUtilizationFixture(named name: String) throws -> PlanUtilizationHistoryBuckets {
        let fixtureURL = URL(fileURLWithPath: #filePath)
            .deletingLastPathComponent()
            .appendingPathComponent("Fixtures", isDirectory: true)
            .appendingPathComponent(name, isDirectory: false)
        let data = try Data(contentsOf: fixtureURL)
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .iso8601
        let document = try decoder.decode(FixtureDocument.self, from: data)
        return PlanUtilizationHistoryBuckets(
            preferredAccountKey: document.preferredAccountKey,
            unscoped: document.unscoped,
            accounts: document.accounts)
    }
}

extension UsageStorePlanUtilizationTests {
    @MainActor
    @Test
    func `global refresh tail does not keep completed provider plan card loading`() {
        let store = Self.makeStore()
        store._setSnapshotForTesting(nil, provider: .claude)
        store.isRefreshing = true
        store.refreshingProviders.insert(.claude)

        #expect(store.shouldShowRefreshingMenuCard(for: .claude))
        #expect(store.shouldShowRefreshingMenuCardIndicator(for: .claude))
        #expect(store.shouldHidePlanUtilizationMenuItem(for: .claude))

        store.refreshingProviders.remove(.claude)

        #expect(store.isRefreshing)
        #expect(store.refreshingProviders.isEmpty)
        #expect(!store.shouldShowRefreshingMenuCard(for: .claude))
        #expect(!store.shouldShowRefreshingMenuCardIndicator(for: .claude))
        #expect(!store.shouldHidePlanUtilizationMenuItem(for: .claude))
    }
}

func planEntry(at capturedAt: Date, usedPercent: Double, resetsAt: Date? = nil) -> PlanUtilizationHistoryEntry {
    PlanUtilizationHistoryEntry(capturedAt: capturedAt, usedPercent: usedPercent, resetsAt: resetsAt)
}

func planSeries(
    name: PlanUtilizationSeriesName,
    windowMinutes: Int,
    entries: [PlanUtilizationHistoryEntry]) -> PlanUtilizationSeriesHistory
{
    PlanUtilizationSeriesHistory(name: name, windowMinutes: windowMinutes, entries: entries)
}

func findSeries(
    _ histories: [PlanUtilizationSeriesHistory],
    name: PlanUtilizationSeriesName,
    windowMinutes: Int) -> PlanUtilizationSeriesHistory?
{
    histories.first { $0.name == name && $0.windowMinutes == windowMinutes }
}

func formattedBoundary(_ date: Date) -> String {
    let formatter = DateFormatter()
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone.current
    formatter.dateFormat = "yyyy-MM-dd HH:mm"
    return formatter.string(from: date)
}
