import Foundation @MainActor @Observable final class AIFreeUsageManager { static let shared = AIFreeUsageManager() static let maxFreeUses = 3 private static let usedCountKey = "AIFreeUsageManager.usedCount" private(set) var usedCount: Int var remainingUses: Int { max(0, Self.maxFreeUses - usedCount) } var hasExhaustedFreeUses: Bool { usedCount >= Self.maxFreeUses } func canUseFreeLiveAI(hasEverPurchasedPremium: Bool) -> Bool { !hasEverPurchasedPremium && remainingUses > 0 } private init() { usedCount = UserDefaults.standard.integer(forKey: Self.usedCountKey) } func recordUse(for tool: AIHistoryToolKind) { guard usedCount < Self.maxFreeUses else { return } usedCount += 1 persistUsedCount() } /// Restores the free AI quota for users who have never purchased premium (e.g. sandbox transaction reset). func resetFreeUses() { usedCount = 0 persistUsedCount() } /// Permanently removes free AI access after a purchase or refund. func forfeitFreeUses() { usedCount = Self.maxFreeUses persistUsedCount() } private func persistUsedCount() { UserDefaults.standard.set(usedCount, forKey: Self.usedCountKey) } }