//
//  AppDelegate.swift
//  relax.offline.mp3.music
//
//  Created by Mr.Zhou on 2024/5/22.
//

import UIKit
import CoreData
import AVFoundation
import Alamofire
import Tiercel
import Firebase
import GoogleMobileAds
import FacebookCore
import StoreKit
@_exported import IQKeyboardManagerSwift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    //当前页面状态
    var showStatus:Bool!
    // 用来保存由系统提供的完成处理器
    var backgroundSessionCompletionHandler: (() -> Void)?
    //退到后台的时间值
    private var backgroundEntryTime:Date?
    //B面
    private var positiceVC:MPPositive_TabBarController!
    //推送要求
    private let notificationHandler = NotificationHandler()
    var backgroundTask: UIBackgroundTaskIdentifier = .invalid
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //请求通知权限
        UNUserNotificationCenter.current()
            .requestAuthorization(options: [.alert, .sound, .badge]) {
            (accepted, error) in
            if !accepted {
                print("Users are not allowed to be notified of messages.")
            }
        }
        //切换通知代理
        UNUserNotificationCenter.current().delegate = notificationHandler
        //广告默认ID
        coreDefaultValues()
        ActiveDaysCalculation()
        //FireBase初始化
        FirebaseApp.configure()
        //广告初始化
        MP_AdMobManager.shared.start()
        //启动前销毁所有的下载任务
        MP_DownloadManager.shared.cancelAllTasksIfNeeded()
        setAudioSupport()
        MP_NetWorkManager.shared.requestStatusToYouTube()
        IQKeyboardManager.shared.enable = true
        IQKeyboardManager.shared.shouldResignOnTouchOutside = true
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.backgroundColor = .init(hex: "#161616")
        //关联faceBook
        ApplicationDelegate.shared.application(application,didFinishLaunchingWithOptions: launchOptions)
        //初始化三个控制器
        positiceVC = MPPositive_TabBarController()
        switch_lunch()
        //执行用户启动事件日志
        MP_AnalyticsManager.shared.user_launchAction()
        return true
    }
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:] ) -> Bool {
        ApplicationDelegate.shared.application(app, open: url, sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String, annotation: options[UIApplication.OpenURLOptionsKey.annotation])
    }
    func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
        print("后台任务处理中-\(identifier)")
        if identifier == MP_DownloadManager.shared.session.identifier {
            MP_DownloadManager.shared.session.completionHandler = completionHandler
        }
    }
    //设置播放器会话状态
    func setAudioSupport(){
        //设置会话
        let session = AVAudioSession.sharedInstance()
        do {
            //允许后台活跃,播放以及记录
            try session.setCategory(.playAndRecord, mode: .default, options: [ .allowAirPlay, .allowBluetoothA2DP,.defaultToSpeaker])
            //激活会话
            try session.setActive(true)
            print("成功激活会话")
        } catch {
            print("Failed to set type:\(error.localizedDescription)")
        }
        //响应后台控制
        UIApplication.shared.beginReceivingRemoteControlEvents()
    }
    func setAudioResume() {
        //设置会话
        let session = AVAudioSession.sharedInstance()
        do {
            try session.setCategory(.playAndRecord, mode: .default, options: [ .allowAirPlay, .allowBluetoothA2DP,.defaultToSpeaker])
            //恢复会话
            try session.setActive(true)
            print("恢复会话")
        } catch {
            print("Failed to set type:\(error.localizedDescription)")
        }
    }
    //停止播放器会话
    func setAudioStop() {
        //设置会话
        let session = AVAudioSession.sharedInstance()
        do {
            //中止会话
            try session.setActive(false)
            print("中止会话")
        } catch {
            print("Failed to set type:\(error.localizedDescription)")
        }
    }
    //活跃天数计算
    private func ActiveDaysCalculation() {
        //判断是否存在活跃天数组
        guard var actives = UserDefaults.standard.object(forKey: "ActiveDays") as? [Date] else {
            //首次打开，没有存入数据
            let now = Date().timeZone()
            UserDefaults.standard.setValue([now], forKey: "ActiveDays")
            return
        }
        //存在活跃天数,检索当前时间是否为新的活跃天
        if  let last = actives.last {
            //对比活跃天数组中最后一位与当前时间
            let now = Date().timeZone()
            //确认现在时间值更大
            if now > last {
                let calendar = Calendar.current
                let startDate = calendar.startOfDay(for: last)
                let endDate = calendar.startOfDay(for: now)
                let components = calendar.dateComponents([.day], from: startDate, to: endDate)
                //相差的天数
                let days = components.day ?? 0
                if days > 0 {
                    //活跃的下一天
                    actives.append(now)
                    UserDefaults.standard.setValue(actives, forKey: "ActiveDays")
                }
            }
        }
    }
    //MARK: - 页面跳转
    ///跳转启动页
    func switch_lunch() {
        let lunchVC = MP_LunchViewController()
        //动画设置
        let transtition = CATransition()
        transtition.duration = 0.8
        transtition.timingFunction = .init(name: .easeOut)//外层模糊化
        window?.layer.add(transtition, forKey: "lunch.easeOut")
        window?.rootViewController = lunchVC
        window?.makeKeyAndVisible()
    }
    ///跳转A面
    func switch_aSide() {
        guard showStatus != false else {
            return
        }
        let tabBarVC = MPSideA_TabBarController()
        //动画设置
        let transtition = CATransition()
        transtition.duration = 0.8
        transtition.timingFunction = .init(name: .easeOut)//外层模糊化
        window?.layer.add(transtition, forKey: "aSide.easeOut")
        window?.rootViewController = tabBarVC
        window?.makeKeyAndVisible()
        showStatus = false
    }
    //跳转b面
    func switch_positive() {
        guard showStatus != true else {
            return
        }
        //销毁A面所有内容
        MPSideA_MediaCenterManager.shared.destroySideA()
        MPSideA_VolumeManager.shared.destroySideA()
        
        //动画设置
        let transtition = CATransition()
        transtition.duration = 0.8
        transtition.timingFunction = .init(name: .easeOut)//外层模糊化
        window?.layer.add(transtition, forKey: "positive.easeOut")
        window?.rootViewController = positiceVC
        window?.makeKeyAndVisible()
        showStatus = true
    }
    //MARK: - 前后台检索设置
    //退往后台
    func applicationDidEnterBackground(_ application: UIApplication) {
        //更新当前后台时间节点
        backgroundEntryTime = Date()
    }
    
    //将要进入前台
    func applicationWillEnterForeground(_ application: UIApplication) {

    }

    //进入前台
    func applicationDidBecomeActive(_ application: UIApplication) {
        guard let backDate = backgroundEntryTime else {
            return
        }
        backgroundEntryTime = nil
        //当前时间值
        let currentDate = Date()
        //算出与后台时间节点的差值
        let duration = currentDate.timeIntervalSince(backDate)
        //获取插页间隔时长
        let times = MP_AdMobManager.shared.getOpenAppDuration()
        if duration >= times {
            MP_AdMobManager.shared.showOpenAdIfAvailable(.HOST, completion: nil)
            //超过间隔时长，进行热启动广告展示
            print("返回前台，并展示了热启动广告")
        }else {
            //未超过，无事发生
            print("返回前台")
        }
    }
    //MARK: - 当应用被用户关闭时
    func applicationWillTerminate(_ application: UIApplication) {
        MP_AnalyticsManager.shared.ad_session_total_valueAction()
        print("应用关闭了")
        //检索应用是否播放歌曲
        guard let load = MP_PlayerManager.shared.loadPlayer, let videoId = load.currentVideoId, let songs = load.songVideos else {return}
        //将songs转为数据
        guard let data = coreSongsforJson(songs) else {return}
        //当前音乐情况是否合理加载了数据
        let last:[String:Any] = ["currentVideoId":videoId,
                    "Songs":data]
        UserDefaults.standard.set(last, forKey: "Last_Play_Songs")
        
    }
    
    
    // MARK: - Core Data stack
    lazy var persistentContainer: NSPersistentContainer = {
        /*
         The persistent container for the application. This implementation
         creates and returns a container, having loaded the store for the
         application to it. This property is optional since there are legitimate
         error conditions that could cause the creation of the store to fail.
        */
        let container = NSPersistentContainer(name: "relax.offline.mp3")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                 
                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }
    func adManagerDidShowInterstitial() {
        window?.rootViewController?.setNeedsStatusBarAppearanceUpdate()
    }
}
///访问appDelegate
let accessAppdelegate = ( UIApplication.shared.delegate as! AppDelegate)
///在应用内展示通知
class NotificationHandler: NSObject, UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler:
        @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound, .badge])
         
        // 如果不想显示某个通知，可以直接用空 options 调用 completionHandler:
        // completionHandler([])
    }
}
