import SwiftUI
import FirebaseCore
import FirebaseFirestore
import RevenueCat

@main
struct CloserApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate
    @StateObject private var appState = AppState()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appState)
        }
    }
}

// MARK: - App Delegate

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        FirebaseApp.configure()
        
        // Configure RevenueCat
        #if DEBUG
        Purchases.logLevel = .debug
        #else
        Purchases.logLevel = .warn
        #endif
        Purchases.configure(withAPIKey: Secrets.rcApiKey)
        
        // Configure notifications
        NotificationService.shared.configure()
        
        return true
    }
    
    func application(
        _ application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
    ) {
        Messaging.messaging().apnsToken = deviceToken
        NotificationService.shared.updateFCMToken()
    }
}

// MARK: - App State

@MainActor
final class AppState: ObservableObject {
    @Published var authState: AuthState = .loading
    @Published var currentUser: User?
    @Published var currentCouple: Couple?
    @Published var currentPartner: User?
    @Published var isPremium = false
    
    private let authService = AuthService.shared
    private let firestore = FirestoreService.shared
    private var authTask: Task<Void, Never>?
    private var partnerListener: ListenerRegistration?
    private var observedPartnerId: String?
    
    init() {
        observeAuthState()
    }
    
    func observeAuthState() {
        authTask = Task {
            for await state in authService.authStateStream() {
                self.authState = state
                if case .authenticated(let userId, _) = state {
                    await loadUserData(userId)
                } else {
                    self.currentUser = nil
                    self.currentCouple = nil
                    self.currentPartner = nil
                    self.observePartner(nil)
                }
            }
        }
    }
    
    func loadUserData(_ userId: String) async {
        do {
            let user: User? = try await firestore.getDocument(at: firestore.userDocument(userId))
            self.currentUser = user
            
            if let coupleId = user?.coupleId {
                let couple: Couple? = try await firestore.getDocument(at: firestore.coupleDocument(coupleId))
                self.currentCouple = couple
                let partnerId = couple?.userIds.first { $0 != userId }
                observePartner(partnerId)
            } else {
                self.currentCouple = nil
                observePartner(nil)
            }
        } catch {
            print("Failed to load user data: \(error)")
        }
    }

    private func observePartner(_ partnerId: String?) {
        guard observedPartnerId != partnerId else { return }

        partnerListener?.remove()
        partnerListener = nil
        observedPartnerId = partnerId
        currentPartner = nil

        guard let partnerId else { return }

        partnerListener = firestore.userDocument(partnerId).addSnapshotListener { [weak self] snapshot, error in
            Task { @MainActor in
                guard let self else { return }
                if let error {
                    print("Failed to observe partner profile: \(error)")
                    return
                }
                self.currentPartner = try? snapshot?.data(as: User.self)
            }
        }
    }
    
    func refreshData() async {
        guard case .authenticated(let userId, _) = authState else { return }
        await loadUserData(userId)
    }
    
    deinit {
        authTask?.cancel()
        partnerListener?.remove()
    }
}

// MARK: - Secrets

enum Secrets {
    /// RevenueCat API key — must be set before building
    static let rcApiKey: String = {
        guard let key = Bundle.main.object(forInfoDictionaryKey: "RC_API_KEY") as? String,
              !key.isEmpty, key != "$(RC_API_KEY)" else {
            print("⚠️ RevenueCat API key not configured. Set RC_API_KEY in Info.plist or build settings.")
            return ""
        }
        return key
    }()
}

// MARK: - Import for Messaging

import FirebaseMessaging
