//
//  AppDelegate.swift


import UIKit
import FirebaseCore
import IQKeyboardManagerSwift
import UserNotifications
import WidgetKit
import GoogleMobileAds
import ContactsUI
import FirebaseMessaging
import FirebaseAppCheck

let APPDEL = UIApplication.shared.delegate as! AppDelegate
let Utilities = UtilitiesClass.Shared

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    let userDefaultManager = UserDefaultManager.shared
    var arrCountryCode = [CountryListModel]()
    let countryViewModel = CountryPickerViewModel()
    var objAdManager : AdvertiseManager!
    var isOpenInterstitialAds = false
    var alertVC: UIAlertController?
    var isNotifyRedirection = false
    var dictNotificationUserInfo = [AnyHashable:Any]()
    var isAppForground = false
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        self.window?.makeKeyAndVisible()
        IQKeyboardManager.shared.enable = true
        
        let providerFactory = YourAppCheckProviderFactory()
        AppCheck.setAppCheckProviderFactory(providerFactory)
        
        
        let googlePlistPath: String = Bundle.main.path(forResource: (isProductionMode) ? ("GoogleService-Info") :  ("GoogleService_test-Info"), ofType: "plist")!
        let options = FirebaseOptions(contentsOfFile: googlePlistPath)
        FirebaseApp.configure(options: options!)
       // FirebaseApp.configure()
        
        countryViewModel.getContryListAPI()
        countryViewModel.arrContryListWithCode.bind { _ in
            if self.countryViewModel.arrContryListWithCode.value?.count != 0{
                self.arrCountryCode = self.countryViewModel.arrContryListWithCode.value!
            }
        }
                
        if (getUUIDFromKeychain().count == 0)
        {
            saveDeviceUUIDToKeychain()
        }
        Messaging.messaging().delegate = self
        
        self.objAdManager = AdvertiseManager.sharedInstance
        var dictAdData: Dictionary<String, String> = [:]
        dictAdData[AdvertiseType.Banner.rawValue] = AdvertisementIds.Banner
        dictAdData[AdvertiseType.Interestitial.rawValue] = AdvertisementIds.Interstitial
        dictAdData[AdvertiseType.AppOpen.rawValue] = AdvertisementIds.AppOpen
        self.objAdManager.dictAdIds = dictAdData
        self.objAdManager.isUserSubscribed(false)
       
        
     //   self.autoLogin()
//        WidgetCenter.shared.reloadAllTimelines()
        
        
        return true
    }
    func applicationDidBecomeActive(_ application: UIApplication) {
        
    }
    func applicationDidEnterBackground(_ application: UIApplication) {
        isAppForground = false
    }
    func applicationWillResignActive(_ application: UIApplication) {
        
    }
    
    func applicationWillEnterForeground(_ application: UIApplication) {
        isAppForground = true
        DispatchQueue.main.async {
            if  FIRRemoteManagement.shared.isShowOpenAds && Reachability.isInternetAvailable && !self.isOpenInterstitialAds {
                if FIRRemoteManagement.shared.isShowOpenAdsCount != "0"{
                    UserDefaultManager.shared.openAdsCount += 1
                    if UserDefaultManager.shared.openAdsCount % (Int(FIRRemoteManagement.shared.isShowOpenAdsCount) ?? 0) == 0
                    {
                        self.setupLaunchController(isType: true)
                    }
                }
            }
        }
    }
    func applicationWillTerminate(_ application: UIApplication) {
        
    }
    
 
    private func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions){
        
        if let notifiResponse = options.notificationResponse{
            if notifiResponse.notification.request.trigger is UNPushNotificationTrigger{
                Messaging.messaging().appDidReceiveMessage(notifiResponse.notification.request.content.userInfo)
                NotificationCenter.default.post(name: Notification.Name.ReceivePushNotification, object: nil, userInfo: [PushNotification.notificationType: notifiResponse.notification.request.content.userInfo["type"] as Any])
            }
        }
    }
    
    func setupLaunchController(isType: Bool) {//open loader animation screen when app kill and first time app open
        DispatchQueue.main.async {
            let rootViewController = OpenAdsVC(nibName: "OpenAdsVC", bundle: nil)
            rootViewController.adType = .openAd
            rootViewController.isForgorund = isType
            rootViewController.modalTransitionStyle = .crossDissolve
            rootViewController.modalPresentationStyle = .fullScreen
            
            let root = UIApplication.getTopViewController()
            if ((root as? UIAlertController) != nil){
                self.alertVC = root as? UIAlertController
                (root as? UIAlertController)?.dismiss(animated: true, completion: nil)
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    UIApplication.getTopViewController()?.present(rootViewController, animated: false, completion: nil)
                }
            }else{
                if UIApplication.getTopViewController()?.presentingViewController is OpenAdsVC {}else{
                    UIApplication.getTopViewController()?.present(rootViewController, animated: false, completion: nil)
                }
            }
//            if UIApplication.getTopViewController()?.presentingViewController is OpenAdsVC {}else{
//                DispatchQueue.main.async {
//                    UIApplication.getTopViewController()?.present(rootViewController, animated: false, completion: nil)
//                }
//            }
        }
    }
    
    func autoLogin(){
        let decoder = JSONDecoder()
        if !self.userDefaultManager.loginUserToken.isEmpty{
            do {
                let jsonData = try decoder.decode(UserInfoAPIModel.self, from: self.userDefaultManager.loginUserData)
                if jsonData.user?.is_profile_completed ?? false && !self.userDefaultManager.loginUserToken.isEmpty{
                    self.window = UIWindow(frame: UIScreen.main.bounds)
                    let storyboard = UIStoryboard(name: StoryboardName.mainStoryboard, bundle: nil)
                    let homeVC = storyboard.instantiateViewController(withIdentifier: LWHomeVC.identifier)
                    self.window?.rootViewController = UINavigationController(rootViewController: homeVC)
                    self.window?.makeKeyAndVisible()
                    APIDataManager.shared.callAutoLoginAPI()
                }
                else{
                    let storyboard = UIStoryboard(name: StoryboardName.LandingStoryboard, bundle: nil)
                    let landingVC = storyboard.instantiateViewController(withIdentifier: LWLandingVC.identifier)
                    self.window?.rootViewController = UINavigationController(rootViewController: landingVC)
                    self.window?.makeKeyAndVisible()
                }
            }
            catch{
                debugPrint("UserData is not available")
                let storyboard = UIStoryboard(name: StoryboardName.LandingStoryboard, bundle: nil)
                let landingVC = storyboard.instantiateViewController(withIdentifier: LWLandingVC.identifier)
                self.window?.rootViewController = UINavigationController(rootViewController: landingVC)
                self.window?.makeKeyAndVisible()
            }
        }else{
            let storyboard = UIStoryboard(name: StoryboardName.LandingStoryboard, bundle: nil)
            let landingVC = storyboard.instantiateViewController(withIdentifier: LWLandingVC.identifier)
            self.window?.rootViewController = UINavigationController(rootViewController: landingVC)
            self.window?.makeKeyAndVisible()
        }
       
    }
 
    
    func isUpdateAvailable() throws -> Bool {
        guard let info = Bundle.main.infoDictionary,
              
                let currentVersion = info["CFBundleShortVersionString"] as? String,
              let identifier = info["CFBundleIdentifier"] as? String,
              let url = URL(string: "https://itunes.apple.com/lookup?bundleId=\(identifier)") else {
                  throw VersionError.invalidBundleInfo
              }
        
        let data = try Data(contentsOf: url)
        guard let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any] else {
            throw VersionError.invalidResponse
        }
        
        if let result = (json["results"] as? [Any])?.first as? [String: Any], let liveVersion = result["version"] as? String {
            return currentVersion < liveVersion
        }
        
        throw VersionError.invalidResponse
    }
    
    func showForceUpdateAlert(alertText:String) {
        let alertController = UIAlertController.init(title: APP_NAME_WITH_WIDGET, message:
                                                        alertText, preferredStyle: .alert)
        
        let cancel = UIAlertAction.init(title: Alert_Message.Update, style: .cancel) { (_) in
            
            guard let url = URL(string: APP_STORE_LINK) else {return}
            
            UIApplication.shared.open(url)
            
        }
        alertController.addAction(cancel)
        
        self.window?.rootViewController?.present(alertController, animated: true)
    }
    
    func regiserForRemoteNotification() {
        
        UNUserNotificationCenter.current().delegate = self
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
            
            if granted {
                if UserDefaultManager.shared.loginUserToken != ""{
                    // Call update device token API
                    APIDataManager.shared.updateDeviceToken()
                }
                debugPrint("Remote Notification access granted.")
            }
            else {
                debugPrint("Remote Notification access denied.")
            }
        }
        UIApplication.shared.registerForRemoteNotifications()
        center.removeAllPendingNotificationRequests()
    }
    
    enum VersionError: Error {
        case invalidResponse, invalidBundleInfo
    }
}

//MARK: - Notification Handling Method -
extension AppDelegate : MessagingDelegate, UNUserNotificationCenterDelegate {
    
    //Delegate
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
        debugPrint("RemoteNotificationsWithDeviceToken = \(deviceTokenString)")
        Messaging.messaging().apnsToken = deviceToken
    }
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        debugPrint("Firebase registration token: \(String(describing: fcmToken))")
        
        if fcmToken != nil {
            let dataDict:[String: String] = ["token": fcmToken!]
            NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
            self.userDefaultManager.deviceToken = fcmToken ?? ""
            if UserDefaultManager.shared.loginUserToken != ""{
                // Call update device token API
                APIDataManager.shared.updateDeviceToken()
            }
        }
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Messaging.messaging().appDidReceiveMessage(userInfo)
        
        isNotifyRedirection = true
        dictNotificationUserInfo = userInfo
        completionHandler(.noData)
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        Messaging.messaging().appDidReceiveMessage(userInfo)
        isNotifyRedirection = true
        dictNotificationUserInfo = userInfo
        if !isAppForground{
            NotificationCenter.default.post(name: Notification.Name.ReceivePushNotification, object: nil, userInfo: nil)
        }else{
            NotificatioManager.shared.redirectToSpecificVC()
        }
    
        WidgetCenter.shared.reloadAllTimelines()
        completionHandler()

    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        debugPrint("willPresent Notifications")
        Messaging.messaging().appDidReceiveMessage(notification.request.content.userInfo)
        let currentVc = UIApplication.shared.topViewController()
        if (currentVc is AddFriendViewController){
            NotificationCenter.default.post(name: Notification.Name.UpdateFriendData, object: nil, userInfo: [PushNotification.notificationType: notification.request.content.userInfo["type"] as Any])
        }else if currentVc is HistoryViewController {
            if let vc = UIApplication.shared.topViewController() as? HistoryViewController{
                _ = vc.view
                vc.updateHistoryList(notification: Notification.init(name: Notification.Name.init("")))
            }
        }
        WidgetCenter.shared.reloadAllTimelines()
        completionHandler([.alert, .sound, .badge])
    }
    func setNotifyFlagFalse(){
        if APPDEL.isNotifyRedirection {
            APPDEL.isNotifyRedirection = false
        }
    }
}


class YourAppCheckProviderFactory: NSObject, AppCheckProviderFactory {
  func createProvider(with app: FirebaseApp) -> AppCheckProvider? {
    if #available(iOS 14.0, *) {
      return AppAttestProvider(app: app)
    } else {
      return DeviceCheckProvider(app: app)
    }
  }
}
