//
//  TrustBuilderMfaSampleAppDelegate.swift
//  TrustBuilderMfaSampleApp
//
//  Created by Virgile Oxaran on 11/01/2023.
//

import SwiftUI
import FirebaseCore
import FirebaseMessaging
import os.log

class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
    private var registerPushCallback: ((_ token: String) -> Void)?
    let gcmMessageIDKey = "gcm.message_id"
    func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        UNUserNotificationCenter.current().delegate = self
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: { _, _ in }
        )
        application.registerForRemoteNotifications()
        
        return true
    }

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
            os_log("Permission granted: %@", log: .default, type: .debug, String(describing: granted))
    }}
    
    func application(_ application: UIApplication,
                     didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
      -> UIBackgroundFetchResult {  // Print message ID.
          if let messageID = userInfo[gcmMessageIDKey] {
              os_log("Message ID : %@", log: .default, type: .debug, String(describing: messageID))
          }
          os_log("userInfo :%@", log: .default, type: .debug, String(describing: userInfo))

          return UIBackgroundFetchResult.newData
        }
    
    func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        os_log("Unable to register for remote notifications: %@", log: .default, type: .error, String(describing: error.localizedDescription))
    }
    func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        os_log("APNs token retrieved: %@", log: .default, type: .debug, String(describing: deviceToken))
        Messaging.messaging().apnsToken = deviceToken
        if let token = Messaging.messaging().fcmToken, let callback = registerPushCallback {
            os_log("token : %@", log: .default, type: .debug, String(describing: token))
            callback(token)
        }
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        if let token = fcmToken, let callback = registerPushCallback {
            os_log("token : %@", log: .default, type: .debug, String(describing: token))
            callback(token)
        }
    }
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification) async
    -> UNNotificationPresentationOptions {
        let userInfo = notification.request.content.userInfo
        switch UIApplication.shared.applicationState {
        case .active:
            os_log("Received push message from APNs on Foreground", log: .default, type: .debug)
        case .background:
            os_log("Received push message from APNs on Background", log: .default, type: .debug)
        case .inactive:
            os_log("Received push message from APNs back to Foreground", log: .default, type: .debug)
        @unknown default:
            fatalError()
        }
        os_log("Messaging %@", log: .default, type: .debug , String(describing: Messaging.messaging().appDidReceiveMessage(userInfo)))
        os_log("willPresent %@", log: .default, type: .debug,  String(describing: userInfo))
        os_log("willPresent2 %@", log: .default, type: .debug,  String(describing: notification))
        NotificationCenter.default.post(name: Notification.Name("pushNotification"), object: nil, userInfo: userInfo)
        return [[.alert, .sound]]
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse) async {
        let id = response.notification.request.identifier
        let userInfo = response.notification.request.content.userInfo
        NotificationCenter.default.post(name: Notification.Name("tappedNotification"), object: nil, userInfo: userInfo)
        os_log("Messaging %@",Messaging.messaging().appDidReceiveMessage(userInfo))
        os_log("Received notification with ID = %@", log: .default, type: .debug, String(describing: id))
        os_log("Received notification UserInfo = %@", log: .default, type: .debug, String(describing: userInfo))
    }
}

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