import RevenueCat
import SwiftUI

@MainActor
@Observable
final class PremiumManager: PremiumManaging {
    var availablePackages: [Package] = []
    
    // MARK: - Configuration
    
    /// RevenueCat entitlement identifier - must match your RevenueCat dashboard
    private let entitlementIdentifier = "Selfie Cam by TopDog Pro"
    
    /// Task for listening to customer info updates
    @ObservationIgnored private var customerInfoTask: Task<Void, Never>?
    
    /// Reads the RevenueCat API key from the Secrets configuration file
    private static var apiKey: String {
        let key = (Bundle.main.object(forInfoDictionaryKey: "RevenueCatAPIKey") as? String) ?? ""
        let placeholders = [
            "",
            "YOUR_REVENUECAT_API_KEY_HERE",
            "test_YOUR_TEST_KEY_HERE",
            "appl_YOUR_PRODUCTION_KEY_HERE"
        ]
        #if DEBUG
        let prefix = key.split(separator: "_").first.map(String.init) ?? "missing"
        let keyStatus = key.isEmpty ? "empty" : "present"
        print("ℹ️ [PremiumManager] RevenueCatAPIKey \(keyStatus), prefix=\(prefix)")
        if let infoPath = Bundle.main.path(forResource: "Info", ofType: "plist"),
           let infoDict = NSDictionary(contentsOfFile: infoPath) as? [String: Any] {
            let rawValue = infoDict["RevenueCatAPIKey"] as? String ?? ""
            let rawPrefix = rawValue.split(separator: "_").first.map(String.init) ?? "missing"
            let rawStatus = rawValue.isEmpty ? "empty" : "present"
            print("ℹ️ [PremiumManager] Info.plist RevenueCatAPIKey \(rawStatus), prefix=\(rawPrefix)")
        } else {
            print("ℹ️ [PremiumManager] Info.plist not found in bundle")
        }
        #endif
        guard !placeholders.contains(key) else {
            #if DEBUG
            print("⚠️ [PremiumManager] RevenueCat API key not configured. Check Secrets.debug.xcconfig / Secrets.release.xcconfig")
            #endif
            return ""
        }
        return key
    }
    
    // MARK: - Debug Override

    /// Debug premium toggle stored in UserDefaults (only available in DEBUG builds)
    @AppStorage("debugPremiumEnabled") @ObservationIgnored private var debugPremiumEnabled = false

    /// Check if debug premium is enabled via UserDefaults toggle or environment variable.
    /// The toggle in Settings > Debug takes precedence over environment variables.
    private var isDebugPremiumEnabled: Bool {
        #if DEBUG
        return debugPremiumEnabled || ProcessInfo.processInfo.environment["ENABLE_DEBUG_PREMIUM"] == "1"
        #else
        return false
        #endif
    }

    /// Public getter/setter for debug premium toggle (DEBUG builds only)
    var isDebugPremiumToggleEnabled: Bool {
        get { debugPremiumEnabled }
        set { debugPremiumEnabled = newValue }
    }
    
    var isPremium: Bool {
        // Debug override takes precedence
        if isDebugPremiumEnabled {
            return true
        }
        
        // If API key isn't configured, return false
        guard !Self.apiKey.isEmpty else {
            return false
        }
        
        return Purchases.shared.cachedCustomerInfo?.entitlements[entitlementIdentifier]?.isActive == true
    }
    
    var isPremiumUnlocked: Bool { isPremium }
    
    init() {
        #if DEBUG
        if isDebugPremiumEnabled {
            print("🔓 [PremiumManager] Debug premium enabled via environment variable")
        }
        #endif
        
        // Only configure RevenueCat if we have a valid API key
        guard !Self.apiKey.isEmpty else {
            #if DEBUG
            print("⚠️ [PremiumManager] Skipping RevenueCat configuration - no API key")
            #endif
            return
        }
        
        #if DEBUG
        Purchases.logLevel = .debug
        #endif
        Purchases.configure(withAPIKey: Self.apiKey)
        
        Task {
            try? await loadProducts()
        }
    }
    
    func loadProducts() async throws {
        guard !Self.apiKey.isEmpty else { return }
        
        let offerings = try await Purchases.shared.offerings()
        if let current = offerings.current {
            availablePackages = current.availablePackages
        }
    }
    
    func purchase(_ package: Package) async throws -> Bool {
        #if DEBUG
        if isDebugPremiumEnabled {
            // Simulate successful purchase in debug mode
            UIAccessibility.post(
                notification: .announcement,
                argument: String(localized: "Debug mode: Purchase simulated!")
            )
            return true
        }
        #endif
        
        let result = try await Purchases.shared.purchase(package: package)
        
        if result.customerInfo.entitlements[entitlementIdentifier]?.isActive == true {
            UIAccessibility.post(
                notification: .announcement,
                argument: String(localized: "Purchase successful! Pro features unlocked.")
            )
            return true
        }
        return false
    }
    
    func purchase(productId: String) async throws {
        #if DEBUG
        if isDebugPremiumEnabled {
            return // Already "premium" in debug mode
        }
        #endif
        
        guard let package = availablePackages.first(where: { $0.storeProduct.productIdentifier == productId }) else {
            throw NSError(
                domain: "PremiumManager",
                code: 1,
                userInfo: [NSLocalizedDescriptionKey: "Product not found"]
            )
        }
        _ = try await purchase(package)
    }
    
    func restorePurchases() async throws {
        #if DEBUG
        if isDebugPremiumEnabled {
            UIAccessibility.post(
                notification: .announcement,
                argument: String(localized: "Debug mode: Restore simulated!")
            )
            return
        }
        #endif
        
        _ = try await Purchases.shared.restorePurchases()
        UIAccessibility.post(
            notification: .announcement,
            argument: String(localized: "Purchases restored")
        )
    }
    
    // MARK: - Subscription Status Check
    
    /// Explicitly fetches fresh customer info from RevenueCat.
    /// Call this on app launch to handle fresh installs where the user
    /// may have an active subscription from another device.
    func checkSubscriptionStatus() async {
        guard !Self.apiKey.isEmpty else { return }
        
        do {
            // Fetch fresh customer info - this updates the cached info used by isPremium
            _ = try await Purchases.shared.customerInfo()
        } catch {
            #if DEBUG
            print("⚠️ [PremiumManager] Failed to fetch customer info: \(error)")
            #endif
        }
    }
    
    // MARK: - Customer Info Listener
    
    /// Starts listening for real-time customer info updates from RevenueCat.
    /// This enables reactive UI updates when subscription status changes
    /// (e.g., user subscribes, cancels, or subscription expires).
    func startListeningForCustomerInfoUpdates() {
        guard !Self.apiKey.isEmpty else { return }
        
        // Cancel any existing listener
        customerInfoTask?.cancel()
        
        customerInfoTask = Task {
            for await customerInfo in Purchases.shared.customerInfoStream {
                let isActive = customerInfo.entitlements[entitlementIdentifier]?.isActive == true
                
                #if DEBUG
                print("📱 [PremiumManager] Customer info updated. Premium: \(isActive)")
                #endif
                
                // The @Observable framework will automatically notify observers
                // when isPremium is accessed after this update since it reads
                // from Purchases.shared.cachedCustomerInfo which is now updated
            }
        }
    }
    
    /// Stops listening for customer info updates.
    /// Call this when the manager is no longer needed.
    func stopListeningForCustomerInfoUpdates() {
        customerInfoTask?.cancel()
        customerInfoTask = nil
    }
}
