import SwiftUI
import Foundation
import SDWebImageSwiftUI
import StoreKit
import SDWebImageSVGCoder
import Alamofire
import UIKit
import UserNotifications

// Firebase imports (requires Firebase SDK via SPM)
#if canImport(FirebaseCore)
import FirebaseCore
#endif
#if canImport(FirebaseAnalytics)
import FirebaseAnalytics
#endif
#if canImport(FirebaseCrashlytics)
import FirebaseCrashlytics
#endif


@main
struct lichunWebsocketApp: App {
    @StateObject private var webSocketService: WebSocketService
    @StateObject private var storeManager: StoreManager
    @StateObject private var gameStateViewModel: GameStateViewModel
    @StateObject private var playerViewModel: PlayerViewModel
    @StateObject private var appViewModel = AppViewModel()
    // INTEGRATION: Phase 3 - Toast notifications
    @StateObject private var toastManager = ToastManager.shared
    // INTEGRATION: Phase 3 - Sound effects
    @StateObject private var soundManager = SoundManager.shared
    // INTEGRATION: Phase 3 - Tooltips
    @StateObject private var tooltipManager: TooltipManager
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    init() {
        // Configure Firebase
        #if canImport(FirebaseCore)
        FirebaseApp.configure()

        // Analytics Configuration
        #if canImport(FirebaseAnalytics)
        Analytics.setAnalyticsCollectionEnabled(true)
        Analytics.setSessionTimeoutInterval(1800) // 30 minutes
        #endif

        // Crashlytics Configuration
        #if canImport(FirebaseCrashlytics)
        #if DEBUG
        Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(false)
        #else
        Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
        #endif
        #endif
        #endif

        let webSocketService = WebSocketService(urlSession: URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue()), delegateQueue: OperationQueue())
        self._webSocketService = StateObject(wrappedValue: webSocketService)

        let storeManager = StoreManager(webSocketService: webSocketService)
        self._storeManager = StateObject(wrappedValue: storeManager)

        let gameStateViewModel = GameStateViewModel(webSocketService: webSocketService)
        self._gameStateViewModel = StateObject(wrappedValue: gameStateViewModel)

        let playerViewModel = PlayerViewModel(webSocketService: webSocketService)
        self._playerViewModel = StateObject(wrappedValue: playerViewModel)

        // INTEGRATION: Initialize TooltipManager with WebSocketService
        let tooltipManager = TooltipManager(webSocketService: webSocketService)
        self._tooltipManager = StateObject(wrappedValue: tooltipManager)

        // Configure SVG image support
        let SVGCoder = SDImageSVGCoder.shared
        SDImageCodersManager.shared.addCoder(SVGCoder)

        UITableView.appearance().backgroundColor = UIColor(named: "background")
        UITabBar.appearance().backgroundColor = UIColor(named: "background")
        UITabBar.appearance().unselectedItemTintColor = UIColor.blue
        let manager = NetworkReachabilityManager(host: "www.apple.com")

        manager?.startListening { status in
            print("Network Status Changed: \(status)")
        }

        // INTEGRATION: Preload common sounds for better performance
        // Use .shared since StateObject shouldn't be accessed before view installation
        SoundManager.shared.preloadSounds([.buttonTap, .success, .error, .purchase, .notification, .achievement])

        // Track app launch
        AnalyticsManager.shared.track(.appLaunched)
    }
    
    var body: some Scene {
        WindowGroup {
            if webSocketService.appLoaded {
                ContentView()
                    .environmentObject(webSocketService)
                    .environmentObject(storeManager)
                    .environmentObject(gameStateViewModel)
                    .environmentObject(playerViewModel)
                    .environmentObject(appViewModel)
                    .environmentObject(toastManager) // INTEGRATION: Toast notifications
                    .environmentObject(soundManager) // INTEGRATION: Sound effects
                    .environmentObject(tooltipManager) // INTEGRATION: Tooltips
                    .onOpenURL { url in
                        // Handle deep links for testing navigation
                        if let route = DeepLinkManager.shared.parse(url: url) {
                            DeepLinkManager.shared.handle(route: route, appViewModel: appViewModel, webSocketService: webSocketService)
                        }
                    }
            } else {
                LoadingView()
            }
        }
    }
}


class AppViewModel: ObservableObject {
    @Published var selectedTab = 0
    @Published var selectedMoreTab: Int?
    @Published var selectedSocialSegment = 0
    @Published var shouldNavigateToRelationships = false

    // MARK: - Navigation State
    @Published var showProfileMenu: Bool = false
    @Published var showMessagesFromHeader: Bool = false
    @Published var showQuickActions: Bool = false
    @Published var showAchievements: Bool = false
    @Published var showRelationships: Bool = false
    @Published var showStore: Bool = false
    @Published var showItems: Bool = false
    // Wave 2 progression surfaces
    @Published var showPerformActivity: Bool = false
    @Published var showLifeGoals: Bool = false
    @Published var showCollection: Bool = false
    @Published var showPrestige: Bool = false

    // MARK: - Header / Game Control State
    /// Vertical scroll offset of the Home tab's ScrollView (0 at top, negative
    /// as the user scrolls down). Drives the collapsing hero header.
    @Published var homeScrollOffset: CGFloat = 0
    /// Local pause state for the time loop. The server has no "paused" flag, so
    /// the header tracks it here and toggles it via the start/stop commands.
    @Published var isGamePaused: Bool = false

    // MARK: - Onboarding State
    @Published var onboardingStep: Int = 0
    @Published var onboardingComplete: Bool = false
    @Published var tutorialTasksComplete: [String: Bool] = [:]

    init() {
        // Load onboarding state from UserDefaults
        self.onboardingComplete = UserDefaults.standard.bool(forKey: "onboardingComplete")
    }

    func markTaskComplete(_ taskId: String) {
        tutorialTasksComplete[taskId] = true
    }

    func isTaskComplete(_ taskId: String) -> Bool {
        return tutorialTasksComplete[taskId] ?? false
    }

    func completeOnboarding() {
        onboardingComplete = true
        UserDefaults.standard.set(true, forKey: "onboardingComplete")
    }
}

class StoreManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    @Published var items: [InAppPurchaseItem] = []
    var webSocketService: WebSocketService
    
    init(webSocketService: WebSocketService) {
        self.webSocketService = webSocketService
        super.init()
        fetchProducts()
        SKPaymentQueue.default().add(self)
    }
    
    deinit {
        SKPaymentQueue.default().remove(self)
    }
    
    func fetchProducts() {
        let productIdentifiers = Set(["diamond1", "diamond2"])
        let productRequest = SKProductsRequest(productIdentifiers: productIdentifiers)
        productRequest.delegate = self
        productRequest.start()
    }

    func purchase(product: SKProduct) {
        let payment = SKPayment(product: product)
        SKPaymentQueue.default().add(payment)
    }
    
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        DispatchQueue.main.async {
            print(response.products)
        }
    }
    
    func request(_ request: SKRequest, didFailWithError error: Error) {
        // Handle the error
        print("Failed to load list of products with error: \(error.localizedDescription)")
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchased:
                // Unlock the consumable content here
                SKPaymentQueue.default().finishTransaction(transaction)
            case .failed:
                // Handle failure
                SKPaymentQueue.default().finishTransaction(transaction)
            default:
                break
            }
        }
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
        return true
    }
}


class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        registerForPushNotifications()
        registerNotificationCategories()
        return true
    }

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
            guard granted else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    /// Register notification categories matching server-side NotificationCategory types.
    /// Categories: life_event, relationship, milestone, holiday, reminder
    func registerNotificationCategories() {
        let lifeEventCategory = UNNotificationCategory(
            identifier: "life_event",
            actions: [],
            intentIdentifiers: [],
            options: .customDismissAction
        )
        let relationshipCategory = UNNotificationCategory(
            identifier: "relationship",
            actions: [],
            intentIdentifiers: [],
            options: .customDismissAction
        )
        let milestoneCategory = UNNotificationCategory(
            identifier: "milestone",
            actions: [],
            intentIdentifiers: [],
            options: .customDismissAction
        )
        let holidayCategory = UNNotificationCategory(
            identifier: "holiday",
            actions: [],
            intentIdentifiers: [],
            options: .customDismissAction
        )
        let reminderCategory = UNNotificationCategory(
            identifier: "reminder",
            actions: [],
            intentIdentifiers: [],
            options: .customDismissAction
        )

        UNUserNotificationCenter.current().setNotificationCategories([
            lifeEventCategory,
            relationshipCategory,
            milestoneCategory,
            holidayCategory,
            reminderCategory,
        ])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        if #available(iOS 14.0, *) {
            // For iOS 14 and later, use .banner and/or .list
            completionHandler([.banner, .sound, .badge])
        } else {
            // For earlier iOS versions, use .alert
            completionHandler([.alert, .sound, .badge])
        }
    }



    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
        let token = tokenParts.joined()
        
        UserDefaults.standard.set(token, forKey: Constants.UserDefaultsKeys.deviceToken)
        NotificationCenter.default.post(
            name: .deviceTokenDidUpdate,
            object: nil,
            userInfo: ["token": token]
        )
        print("Device Token saved: \(token)")
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        // Handle failure
        print("Failed to register: \(error)")
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo

        // Parse deep link from push payload (sent by server as "deepLink" object)
        if let deepLink = userInfo["deepLink"] as? [String: Any],
           let linkType = deepLink["type"] as? String {
            let route: DeepLinkRoute?

            switch linkType {
            case "event":
                route = .home
            case "chat":
                route = .social(segment: .messages)
            case "milestone":
                route = .achievements
            default:
                route = .home
            }

            if let route = route {
                DispatchQueue.main.async {
                    DeepLinkManager.shared.pendingRoute = route
                }
            }
        }

        // Clear badge when user taps a notification
        UIApplication.shared.applicationIconBadgeNumber = 0

        completionHandler()
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Clear the app badge when user opens the app
        UIApplication.shared.applicationIconBadgeNumber = 0
    }
}


//class AppDelegate: NSObject, UIApplicationDelegate {
//    @EnvironmentObject var webSocketService: WebSocketService
//
//    func applicationDidBecomeActive(_ application: UIApplication) {
//        print("delegate connect")
//        webSocketService.connect()
//    }
//
//    func applicationDidEnterBackground(_ application: UIApplication) {
//        webSocketService.disconnect()
//    }
//}
