//
//  MP_AdMobManager.swift
//  relax.offline.mp3.music
//
//  Created by Mr.Zhou on 2024/6/14.
//

import UIKit
import AVFoundation
import GoogleMobileAds

///广告管理器
class MP_AdMobManager: NSObject, GADAudioVideoManagerDelegate, GADFullScreenContentDelegate, GADNativeAdLoaderDelegate, GADNativeAdDelegate, GADVideoControllerDelegate {
    static let shared = MP_AdMobManager()
    private let sharedInstance = GADMobileAds.sharedInstance()
    ///广告总开关
    private var openAdStatus:Bool = true
    ///广告过期时间(50分钟)
    private let expirationTime:TimeInterval = 3000
    
    //检测广告是否过期
    private func wasAdexpirationTime(_ date:Date?) -> Bool {
        guard let loadTime = date else { return false }
        // Check if ad was loaded more than four hours ago.
        return Date().timeIntervalSince(loadTime) < expirationTime
    }
    //MARK: - 插页广告总设置
    ///插页广告总开关
    private var interstitialSwitch:Bool = false{
        didSet{
            DispatchQueue.main.async {
                [weak self] in
                MP_PlayerManager.shared.isAdLate = self?.interstitialSwitch
                MPSideA_MediaCenterManager.shared.isAdLate = self?.interstitialSwitch
            }
        }
    }
    ///插页广告显示时间
    var interstitialDate:Date?
    ///插页广告间隔秒数(默认40秒)
    private var interstitialDuration:TimeInterval = 40
    ///设置插页总开关
    func setInterstitialSwitch(_ status:Bool) {
        interstitialSwitch = status
    }
    ///获得插页开关的状态
    func getInterstitialSwitch() -> Bool {
        return interstitialSwitch
    }
    ///设置插页广告间隔秒数
    func setInterstitialDuration(_ duration:TimeInterval?) {
        self.interstitialDuration = duration ?? 30
    }
    ///是否达到插页间隔时长（达到即可继续展示插页广告）
    private func isShowInterstitialADAvailable(_ date:Date) -> Bool {
        return Date().timeIntervalSince(date) > interstitialDuration
    }
    private override init() {
        super.init()
        GADMobileAds.sharedInstance().audioVideoManager.delegate = self
        GADMobileAds.sharedInstance().audioVideoManager.audioSessionIsApplicationManaged = false
        reloadAdMobIDs()
        //对开屏广告完成处理闭包
        completeOpenAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的开屏广告实例
            appOpenAd = nil
            appInterstitialAd = nil
            isShowingOpenAd = false
            loadOpenAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的开屏广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
                [weak self] in
                self?.loadOpenAd(.HOST) { status in
                    if status == true {
                        print("新的开屏广告加载成功")
                    }else {
                        print("开屏广告加载失败了")
                    }
                }
            }
        }
        //搜索插页广告完成处理闭包
        completeSearchInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的搜索插页广告实例
            searchInterstitialAd = nil
            isShowingSearchInterstitialAd = false
            loadSearchInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的搜索插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadSearchInterstitialAd { status in
                    if status {
                        print("成功加载搜索插页广告")
                    }else {
                        print("搜索插页广告加载失败")
                    }
                }
            }
        }
        //播放插页广告完成处理闭包
        completePlayInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的播放插页广告实例
            playInterstitialAd = nil
            isShowingPlayInterstitialAd = false
            loadPlayInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的播放插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadPlayInterstitialAd { status in
                    if status {
                        print("成功加载播放插页广告")
                    }else {
                        print("播放插页广告加载失败")
                    }
                }
            }
        }
        //切歌插页
        completeSwitchInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的切歌插页广告实例
            switchInterstitialAd = nil
            isShowingSwitchInterstitialAd = false
            loadSwitchInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的切歌插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadSwitchInterstitialAd { status in
                    if status {
                        print("成功加载切歌插页广告")
                    }else {
                        print("切歌插页广告加载失败")
                    }
                }
            }
        }
        //下载插页
        completeLoadInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的切歌插页广告实例
            loadInterstitialAd = nil
            isShowingLoadInterstitialAd = false
            loadLoadInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的下载插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadLoadInterstitialAd { status in
                    if status {
                        print("成功加载下载插页广告")
                    }else {
                        print("下载插页广告加载失败")
                    }
                }
            }
        }
        //曲库插页广告完成处理闭包
        completeLibraryInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的曲库插页广告实例
            libraryInterstitialAd = nil
            isShowingLibraryInterstitialAd = false
            loadLibraryInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的曲库插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadLibraryInterstitialAd { status in
                    if status {
                        print("成功加载曲库插页广告")
                    }else {
                        print("曲库插页广告加载失败")
                    }
                }
            }
        }
        //全局插页广告完成处理闭包
        completeGlobalInterstitialAdBlock = {
            [weak self] in
            guard let self = self, interstitialSwitch == true else {return}
            //销毁现在的全局插页广告实例
            globalInterstitialAd = nil
            isShowingGlobalInterstitialAd = false
            loadGlobalInterstitialAdTime = nil
            //关闭插页广告开关
            interstitialSwitch = false
            //重新加载后续的全局插页广告
            DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
                [weak self] in
                self?.loadGlobalInterstitialAd { status in
                    if status {
                        print("成功加载全局插页广告")
                    }else {
                        print("全局插页广告加载失败")
                    }
                }
            }
        }
    }
    ///更新ID
    func reloadAdMobIDs() {
        //更新所有广告ID
        if let data = UserDefaults.standard.object(forKey: "OpenICEID") as? Data, let array = jsonforCoreAdModel(data) {
            print("成功提取ID")
            OpenICEID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "OpenHOSTID") as? Data, let array = jsonforCoreAdModel(data) {
            OpenHOSTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "SearchINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            SearchINSERTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "SearchNATIVEID") as? Data, let array = jsonforCoreAdModel(data) {
            SearchNATIVEID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "PlayerINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            PlayerINSERTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "SwitchINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            SwitchINSERTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "LoadINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            LoadINSERTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "LibraryINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            LibraryINSERTID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "LibraryNATIVEID") as? Data, let array = jsonforCoreAdModel(data) {
            LibraryNATIVEID = array.sorted(by: {$0.level > $1.level})
        }
        if let data = UserDefaults.standard.object(forKey: "GlobalINSERTID") as? Data, let array = jsonforCoreAdModel(data) {
            GlobalINSERTID = array.sorted(by: {$0.level > $1.level})
        }
    }
    ///加载更多广告
    func loadMoreAdMobs() {
        guard openAdStatus else {return}
        loadPlayInterstitialAd{status in
            if status {
                print("成功加载播放插页广告")
            }else {
                print("播放插页广告加载失败")
            }
            self.loadSearchInterstitialAd { status in
                if status {
                    print("成功加载搜索插页广告")
                }else {
                    print("搜索插页广告加载失败")
                }
            }
        }
    }
    func loadAnyAdMobs() {
        guard openAdStatus else {return}
        let serialQueue = DispatchQueue(label: "com.yourapp.serialQueue")
        serialQueue.async { [weak self] in
            self?.loadSwitchInterstitialAd { status in
                if status {
                    print("成功加载切歌插页广告")
                }else {
                    print("切歌插页广告加载失败")
                }
                self?.loadLoadInterstitialAd { status in
                    if status {
                        print("成功加载下载插页广告")
                    }else {
                        print("下载插页广告加载失败")
                    }
                    self?.loadLibraryInterstitialAd { status in
                        if status {
                            print("成功加载曲库插页广告")
                        }else {
                            print("曲库插页广告加载失败")
                        }
                        self?.loadGlobalInterstitialAd { status in
                            if status {
                                print("成功加载全局插页广告")
                            }else {
                                print("全局插页广告加载失败")
                            }
                        }
                    }
                }
            }
        }
    }
    deinit{
        displaySearchTimer?.invalidate()
        displaySearchTimer = nil
        displayLibraryTimer?.invalidate()
        displayLibraryTimer = nil
    }
    ///开始缓存广告
    func start() {
        sharedInstance.start { status in
            print("App启动，开始加载广告")
        }
    }
    
    
    //MARK: - 开屏
    //开屏冷启动广告ID
    private var OpenICEID:[MPPositive_AdModelModel] = []
    //开屏热启动广告ID
    private var OpenHOSTID:[MPPositive_AdModelModel] = []
    //开屏广告类型
    enum OpenType:Int {
        //冷启动
        case ICE = 0
        //热启动
        case HOST = 1
        var title:String{
            switch self {
            case .ICE:
                return "是冷启动开屏广告"
            case .HOST:
                return "是热启动开屏广告"
            }
        }
    }
    //应用开屏广告实例
    var appOpenAd:GADAppOpenAd?
    //应用插页广告实例
    var appInterstitialAd:GADInterstitialAd?
    //是否正在加载广告
    private var isLoadingOpenAd:Bool = false
    //是否正在展示广告
    var isShowingOpenAd:Bool = false
    //开屏广告加载时间
    private var loadOpenAdTime:Date?
    //开屏广告时间间隔(默认5秒)
    private var openAppDuration:TimeInterval = 10
    //设置开屏广告时间间隔
    func setOpenAppDuration(_ duration:TimeInterval) {
        self.openAppDuration = duration
    }
    //获取开屏广告时间间隔
    func getOpenAppDuration() -> TimeInterval {
        return self.openAppDuration
    }
    //开屏广告加载完成处理闭包
    var completeOpenAdBlock:(() -> Void)?
    
    ///异步加载开屏广告
    func loadOpenAd(_ type:OpenType, level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        //检索是否超过了对应的id组的阶级数量
        var item:MPPositive_AdModelModel
        switch type {
        case .ICE:
            guard level <= (OpenICEID.count-1) else {
                print("冷启动广告组已经全部加载失败，停止继续加载")
                completion(false)
                return
            }
            item = OpenICEID[level]
        case .HOST:
            guard level <= (OpenHOSTID.count-1) else {
                print("热启动广告组已经全部加载失败，停止继续加载")
                completion(false)
                return
            }
            item = OpenHOSTID[level]
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingOpenAd || isOpenAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingOpenAd = true
        //判断需要生成什么广告
        if item.type == .Open {
            //生成开屏广告
            // 使用 GADAppOpenAd 的 load 方法和一个completion handler来加载广告
            GADAppOpenAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    if let error = error  {
                        print("加载开屏广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                        self.isLoadingOpenAd = false
                        loadOpenAd(type, level: level+1, completion: completion)
                    } else {
                        self.appOpenAd = ad
                        self.isLoadingOpenAd = false
                        //实现代理
                        self.appOpenAd?.fullScreenContentDelegate = self
                        //更新加载时间
                        self.loadOpenAdTime = Date()
                        completion(true)
                    }
                }
            }
        }else if item.type == .Insert {
            //生成插页广告
            GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
                DispatchQueue.main.async { [weak self] in
                    guard let self = self else { return }
                    if let error = error  {
                        print("加载开屏广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                        self.isLoadingOpenAd = false
                        loadOpenAd(type, level: level+1, completion: completion)
                    } else {
                        self.appInterstitialAd = ad
                        self.isLoadingOpenAd = false
                        //实现代理
                        self.appInterstitialAd?.fullScreenContentDelegate = self
                        //更新加载时间
                        self.loadOpenAdTime = Date()
                        completion(true)
                    }
                }
            }
        }else {
            completion(false)
        }
    }
    ///开屏广告展示
    func showOpenAdIfAvailable(_ type:OpenType, completion:((_ T:GADFullScreenPresentingAd, _ isOpen:Bool) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingOpenAd else { return }
        // 如果应用开屏广告尚不可用但应该显示，则加载新广告。
        if !isOpenAdAvailable() {
            loadOpenAd(type) { [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showOpenAdIfAvailable(type, completion: completion)
                }
            }
            return
        }
        if type == .ICE {
            MP_AnalyticsManager.shared.cold_ads_chanceAction()
        }else {
            MP_AnalyticsManager.shared.hot_ads_chanceAction()
        }
        //当开屏广告确定有值后展示
        if let ad = (appOpenAd) {
            //传递加载完成事件
            if let block = completion {
                block(ad, true)
            }else {
                isShowingOpenAd = true
                interstitialSwitch = true
                DispatchQueue.main.async {
                    [weak self] in
                    guard let self = self else {return}
                    do{
                        try ad.canPresent(fromRootViewController: nil)
                        ad.present(fromRootViewController: nil)
                        
                    }catch{
                        print("开屏广告展示失败，失败原因:\(error)")
                        if completeOpenAdBlock != nil {
                            completeOpenAdBlock!()
                        }
                    }
                }
            }
        }else if let ad = (appInterstitialAd) {
            //传递加载完成事件
            if let block = completion {
                block(ad, false)
            }else {
                isShowingOpenAd = true
                interstitialSwitch = true
                DispatchQueue.main.async {
                    [weak self] in
                    guard let self = self else {return}
                    do{
                        try ad.canPresent(fromRootViewController: nil)
                        ad.present(fromRootViewController: nil)
                    }catch{
                        print("开屏广告展示失败，失败原因:\(error)")
                        if completeOpenAdBlock != nil {
                            completeOpenAdBlock!()
                        }
                    }
                }
            }
        }else {
            if type == .ICE {
                MP_AnalyticsManager.shared.cold_ads_showFailureAction("Ad loading failed")
            }else {
                MP_AnalyticsManager.shared.hot_ads_showFailureAction("Ad loading failed")
            }
        }
    }
    ///查询是否有开屏广告
    func isOpenAdAvailable() -> Bool {
        return (appOpenAd != nil || appInterstitialAd != nil) && wasAdexpirationTime(loadOpenAdTime)
    }
    
    //MARK: - 搜索
    //搜索插页广告ID
    private var SearchINSERTID:[MPPositive_AdModelModel] = []
    //搜索原生广告ID
    private var SearchNATIVEID:[MPPositive_AdModelModel] = []
    ///搜索插页广告
    private var searchInterstitialAd:GADInterstitialAd?
    ///是否正在加载搜索插页广告
    private var isLoadingSearchInterstitialAd:Bool = false
    ///是否正在展示搜索插页广告
    var isShowingSearchInterstitialAd:Bool = false
    ///搜索插页加载时间
    private var loadSearchInterstitialAdTime:Date?
    ///搜索广告处理闭包
    var completeSearchInterstitialAdBlock:(() -> Void)?
    ///搜索原生广告加载器
    var searchAdLoader:GADAdLoader?
    ///搜索原生广告
    var searchNativeAd:GADNativeAd?
    ///搜索原生广告视图
    var searchNativeAdView:GADNativeAdView?
    ///搜索原生存储时长
    var refreshSearchTimes:TimeInterval = 3600
    ///搜索原生显示刷新计时器
    var displaySearchTimer:Timer?
    ///搜索原生加载时间
    var expirationSearchDate:Date?
    ///搜索控制器
    var searchViewController:UIViewController?
    ///搜索原生回调闭包
    var onSearchNativeAdBlock:(() -> Void)?
    ///配置搜索原生广告加载器
    func configureSreachNativeAd(rootController vc:UIViewController) {
        searchViewController = vc
    }
    ///搜索原生广告加载
    func loadSearchNativeAd() {
        guard openAdStatus else {return}
        guard let vc = searchViewController else {return}
        //请求数量限制器
        let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
        //加载一条，每次即使结束后重新刷新数据
        multipleAdOptions.numberOfAds = 1
        //图片加载限制器
        let imageAdOptions = GADNativeAdImageAdLoaderOptions()
        imageAdOptions.shouldRequestMultipleImages = false
        //视频加载限制器
        let videoAdOptions = GADVideoOptions()
        videoAdOptions.startMuted = true
        if let first = SearchNATIVEID.first, first.type == .Native {
            MP_AnalyticsManager.shared.result_ads_chanceAction()
            searchAdLoader = GADAdLoader(adUnitID: first.identifier, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions, imageAdOptions, videoAdOptions])
            searchAdLoader?.delegate = self
            searchAdLoader?.load(GADRequest())
        }
    }
    ///将加载的搜索原生广告添加到页面中
    func layoutSearchNativeAd(in containerView: UIView) {
        guard openAdStatus else {return}
        containerView.subviews.forEach { item in
            item.removeFromSuperview()
        }
        searchNativeAdView = nil
        //初始化广告模版对象
        guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAd = searchNativeAd, refreshSearchDate(expirationSearchDate) else {
            //重新加载
            loadSearchNativeAd()
            return
        }
        searchNativeAdView = templateView
        nativeAd.delegate = self
        containerView.addSubview(templateView)
        templateView.snp.makeConstraints { make in
            make.top.bottom.equalToSuperview()
            make.left.equalToSuperview().offset(16*width)
            make.right.equalToSuperview().offset(-16*width)
        }
        //创建一个choiveView
        let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
        let customAdChoicesView = GADAdChoicesView(frame: customRect)
        templateView.addSubview(customAdChoicesView)
        templateView.adChoicesView = customAdChoicesView
        containerView.snp.updateConstraints { make in
            make.height.equalTo(125)
        }
        templateView.nativeAd = nativeAd
        nativeAd.paidEventHandler = { adValue in
            MP_AnalyticsManager.shared.result_ads_showAction(nativeAd.responseInfo, adValue: adValue)
        }
        // 设置展示计时器，60 秒后刷新加载新广告
        displaySearchTimer?.invalidate()
        displaySearchTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { [weak self] _ in
            self?.loadSearchNativeAd()
        }
    }
    ///搜索原生存储时长
    private func refreshSearchDate(_ date:Date?) -> Bool {
        guard let date = date else {return false}
        return Date().timeIntervalSince(date) < refreshSearchTimes
    }
    
    //异步加载搜索插页广告
    func loadSearchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (SearchINSERTID.count-1) else {
            print("搜索插页广告组已经全部加载失败，停止继续加载")
            //开始加载全局插页
            loadGlobalInterstitialAd { status in
                completion(status)
            }
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingSearchInterstitialAd || isSearchInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingSearchInterstitialAd = true
        let item = SearchINSERTID[level]
        //加载搜索插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载搜索插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingSearchInterstitialAd = false
                    loadSearchInterstitialAd(level+1, completion: completion)
                } else {
                    self.searchInterstitialAd = ad
                    self.isLoadingSearchInterstitialAd = false
                    //实现代理
                    self.searchInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadSearchInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///搜索插页广告展示
    func showSearchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingSearchInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果搜索广告尚不可用但应该显示，则加载新广告。
        if !isSearchInterstitialAdAvailable() {
            loadSearchInterstitialAd { [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showSearchInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        MP_AnalyticsManager.shared.search_ads_chanceAction()
        //当搜索插页广告确定有值后展示
        if let ad = searchInterstitialAd {
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingSearchInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else if let ad = globalInterstitialAd {
            //加载全局插页广告
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else {
            MP_AnalyticsManager.shared.search_ads_showFailureAction("Ad loading failed")
        }
    }
    //查询是否有搜索插页广告
    func isSearchInterstitialAdAvailable() -> Bool {
        return searchInterstitialAd != nil && wasAdexpirationTime(loadSearchInterstitialAdTime)
    }
    
    //MARK: - 播放
    //播放插页广告ID
    private var PlayerINSERTID:[MPPositive_AdModelModel] = []
    ///播放插页广告
    var playInterstitialAd:GADInterstitialAd?
    ///是否正在加载播放插页广告
    private var isLoadingPlayInterstitialAd:Bool = false
    ///是否正在展示播放插页广告
    var isShowingPlayInterstitialAd:Bool = false
    ///播放插页加载时间
    private var loadPlayInterstitialAdTime:Date?
    ///播放广告处理闭包
    var completePlayInterstitialAdBlock:(() -> Void)?
    //异步加载播放插页广告
    func loadPlayInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (PlayerINSERTID.count-1) else {
            print("播放插页广告组已经全部加载失败，停止继续加载")
            //开始加载全局插页
            loadGlobalInterstitialAd { status in
                completion(status)
            }
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingPlayInterstitialAd || isPlayInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingPlayInterstitialAd = true
        let item = PlayerINSERTID[level]
        //加载播放插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载播放插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingPlayInterstitialAd = false
                    loadPlayInterstitialAd(level+1, completion: completion)
                } else {
                    self.playInterstitialAd = ad
                    self.isLoadingPlayInterstitialAd = false
                    //实现代理
                    self.playInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadPlayInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///播放插页广告展示
    func showPlayInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingPlayInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果播放插页广告尚不可用但应该显示，则加载新广告。
        if !isPlayInterstitialAdAvailable() {
            loadPlayInterstitialAd{ [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showPlayInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        MP_AnalyticsManager.shared.play_ads_chanceAction()
        //当播放插页广告确定有值后展示
        if let ad = playInterstitialAd {
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingPlayInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else if let ad = globalInterstitialAd {
            //加载全局插页广告
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else {
            MP_AnalyticsManager.shared.play_ads_showFailureAction("Ad loading failed")
        }
    }
    //查询是否有播放插页广告
    func isPlayInterstitialAdAvailable() -> Bool {
        return playInterstitialAd != nil && wasAdexpirationTime(loadPlayInterstitialAdTime)
    }
    
    
    //MARK: - 切歌
    //切歌插页广告ID
    private var SwitchINSERTID:[MPPositive_AdModelModel] = []
    ///切歌插页广告
    var switchInterstitialAd:GADInterstitialAd?
    ///是否正在加载切歌插页广告
    private var isLoadingSwitchInterstitialAd:Bool = false
    ///是否正在展示切歌插页广告
    var isShowingSwitchInterstitialAd:Bool = false
    ///切歌插页加载时间
    private var loadSwitchInterstitialAdTime:Date?
    ///切歌广告处理闭包
    var completeSwitchInterstitialAdBlock:(() -> Void)?
    //异步加载切歌插页广告
    func loadSwitchInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (SwitchINSERTID.count-1) else {
            print("切歌插页广告组已经全部加载失败，停止继续加载")
            //开始加载全局插页
            loadGlobalInterstitialAd { status in
                completion(status)
            }
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingSwitchInterstitialAd || isSwitchInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingSwitchInterstitialAd = true
        let item = SwitchINSERTID[level]
        //加载播放插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载切歌插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingSwitchInterstitialAd = false
                    loadSwitchInterstitialAd(level+1, completion: completion)
                } else {
                    self.switchInterstitialAd = ad
                    self.isLoadingSwitchInterstitialAd = false
                    //实现代理
                    self.switchInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadSwitchInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///切歌插页广告展示
    func showSwitchInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingSwitchInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果切歌插页广告尚不可用但应该显示，则加载新广告。
        if !isSwitchInterstitialAdAvailable() {
            loadSwitchInterstitialAd{ [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showSwitchInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        MP_AnalyticsManager.shared.cut_ads_chanceAction()
        //当切歌插页广告确定有值后展示
        if let ad = switchInterstitialAd {
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingSwitchInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else if let ad = globalInterstitialAd {
            //加载全局插页广告
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else {
            MP_AnalyticsManager.shared.cut_ads_showFailureAction("Ad loading failed")
        }
    }
    //查询是否有切歌插页广告
    func isSwitchInterstitialAdAvailable() -> Bool {
        return switchInterstitialAd != nil && wasAdexpirationTime(loadSwitchInterstitialAdTime)
    }
    
    //MARK: - 下载
    //下载插页广告ID
    private var LoadINSERTID:[MPPositive_AdModelModel] = []
    ///下载插页广告
    var loadInterstitialAd:GADInterstitialAd?
    ///是否正在加载下载插页广告
    private var isLoadingLoadInterstitialAd:Bool = false
    ///是否正在展示下载插页广告
    var isShowingLoadInterstitialAd:Bool = false
    ///下载插页加载时间
    private var loadLoadInterstitialAdTime:Date?
    ///下载广告处理闭包
    var completeLoadInterstitialAdBlock:(() -> Void)?
    //异步加载下载插页广告
    func loadLoadInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (LoadINSERTID.count-1) else {
            print("下载插页广告组已经全部加载失败，停止继续加载")
            //开始加载全局插页
            loadGlobalInterstitialAd { status in
                completion(status)
            }
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingLoadInterstitialAd || isLoadInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingLoadInterstitialAd = true
        let item = LoadINSERTID[level]
        //加载下载插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载下载插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingLoadInterstitialAd = false
                    loadLoadInterstitialAd(level+1, completion: completion)
                } else {
                    self.loadInterstitialAd = ad
                    self.isLoadingLoadInterstitialAd = false
                    //实现代理
                    self.loadInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadLoadInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///下载插页广告展示
    func showLoadInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingLoadInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果下载插页广告尚不可用但应该显示，则加载新广告。
        if !isLoadInterstitialAdAvailable() {
            loadLoadInterstitialAd{ [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showLoadInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        MP_AnalyticsManager.shared.dl_ads_chanceAction()
        //当下载插页广告确定有值后展示
        if let ad = loadInterstitialAd {
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingLoadInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else if let ad = globalInterstitialAd {
            //加载全局插页广告
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else {
            MP_AnalyticsManager.shared.dl_ads_showFailureAction("Ad loading failed")
        }
    }
    //查询是否有下载插页广告
    func isLoadInterstitialAdAvailable() -> Bool {
        return loadInterstitialAd != nil && wasAdexpirationTime(loadLoadInterstitialAdTime)
    }
    //MARK: - 曲库
    //曲库插页ID
    private var LibraryINSERTID:[MPPositive_AdModelModel] = []
    //曲库原生ID
    private var LibraryNATIVEID:[MPPositive_AdModelModel] = []
    ///曲库插页广告
    private var libraryInterstitialAd:GADInterstitialAd?
    ///是否正在加载曲库插页广告
    private var isLoadingLibraryInterstitialAd:Bool = false
    ///是否正在展示曲库插页广告
    var isShowingLibraryInterstitialAd:Bool = false
    ///曲库插页加载时间
    private var loadLibraryInterstitialAdTime:Date?
    ///曲库广告处理闭包
    var completeLibraryInterstitialAdBlock:(() -> Void)?
    ///搜索原生广告加载器
    var libraryAdLoader:GADAdLoader?
    ///搜索原生广告
    var libraryNativeAds:[GADNativeAd]?
    ///搜索原生广告视图一
    var libraryNativeAdFirstView:GADNativeAdView?
    ///原生广告视图二
    var libraryNativeAdSecondView:GADNativeAdView?
    ///搜索原生存储时长
    var refreshLibraryTimes:TimeInterval = 3600
    ///搜索原生显示刷新计时器
    var displayLibraryTimer:Timer?
    ///搜索原生加载时间
    var expirationLibraryDate:Date?
    ///搜索控制器
    var libraryViewController:UIViewController?
    ///搜索原生回调闭包
    var onLibraryNativeAdBlock:(() -> Void)?
    ///配置搜索原生广告加载器
    func configureLibraryNativeAd(rootController vc:UIViewController) {
        guard openAdStatus else {return}
        if libraryViewController == nil {
            libraryViewController = vc
        }
    }
    ///搜索原生广告加载
    func loadLibraryNativeAd() {
        guard openAdStatus else {return}
        guard let vc = libraryViewController, libraryNativeAds == nil else {return}
        //请求数量限制器
        let multipleAdOptions = GADMultipleAdsAdLoaderOptions()
        //加载一条，每次即使结束后重新刷新数据
        multipleAdOptions.numberOfAds = 2
        //图片加载限制器
        let imageAdOptions = GADNativeAdImageAdLoaderOptions()
        imageAdOptions.shouldRequestMultipleImages = false
        //视频加载限制器
        let videoAdOptions = GADVideoOptions()
        videoAdOptions.startMuted = true
        if let first = LibraryNATIVEID.first, first.type == .Native  {
            libraryAdLoader = GADAdLoader(adUnitID: first.identifier, rootViewController: vc, adTypes: [.native], options: [multipleAdOptions,imageAdOptions,videoAdOptions])
            libraryAdLoader?.delegate = self
            libraryAdLoader?.load(GADRequest())
            libraryNativeAds = []
        }
    }
    ///将加载的搜索原生广告添加到页面中
    func layoutLibraryNativeAd(in containerView: UIView, index:Int) {
        guard openAdStatus else {return}
        containerView.subviews.forEach { item in
            item.removeFromSuperview()
        }
        if index == 0 {
            MP_AnalyticsManager.shared.lbr_ads_chanceAction()
            //曲库第一页
            libraryNativeAdFirstView = nil
            //初始化广告模版对象
            guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAds = libraryNativeAds, nativeAds.count == 2, let nativeAd = nativeAds.first, refreshLibraryDate(expirationLibraryDate) else {
                //重新加载
                loadLibraryNativeAd()
                return
            }
            libraryNativeAdFirstView = templateView
            nativeAd.delegate = self
            containerView.addSubview(templateView)
            templateView.snp.makeConstraints { make in
                make.top.bottom.equalToSuperview()
                make.left.equalToSuperview().offset(16*width)
                make.right.equalToSuperview().offset(-16*width)
            }
            //创建一个choiveView
            let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
            let customAdChoicesView = GADAdChoicesView(frame: customRect)
            templateView.addSubview(customAdChoicesView)
            templateView.adChoicesView = customAdChoicesView
            templateView.nativeAd = nativeAd
            nativeAd.paidEventHandler = { adValue in
                MP_AnalyticsManager.shared.lbr_ads_showAction(nativeAd.responseInfo, adValue: adValue)
            }
        }else {
            MP_AnalyticsManager.shared.list_ads_chanceAction()
            //曲库第二页
            libraryNativeAdSecondView = nil
            //初始化广告模版对象
            guard let templateView = (Bundle.main.loadNibNamed("GADTSmallTemplateView", owner: nil, options: nil)?.first as? GADTTemplateView), let nativeAds = libraryNativeAds, nativeAds.count == 2, let nativeAd = nativeAds.last, refreshLibraryDate(expirationLibraryDate) else {
                //重新加载
                loadLibraryNativeAd()
                return
            }
            libraryNativeAdSecondView = templateView
            nativeAd.delegate = self
            containerView.addSubview(templateView)
            templateView.snp.makeConstraints { make in
                make.top.bottom.equalToSuperview()
                make.left.equalToSuperview().offset(16*width)
                make.right.equalToSuperview().offset(-16*width)
            }
            //创建一个choiveView
            let customRect = CGRect(x: containerView.frame.width-(16*width)-25, y: 0, width: 25, height: 25)
            let customAdChoicesView = GADAdChoicesView(frame: customRect)
            templateView.addSubview(customAdChoicesView)
            templateView.adChoicesView = customAdChoicesView
            templateView.nativeAd = nativeAd
            nativeAd.paidEventHandler = { adValue in
                MP_AnalyticsManager.shared.list_ads_showAction(nativeAd.responseInfo, adValue: adValue)
            }
        }
        DispatchQueue.main.async {
            [weak self] in
            containerView.snp.updateConstraints { make in
                make.height.equalTo(125)
            }
        }
        // 设置展示计时器，60 秒后刷新加载新广告
        displayLibraryTimer?.invalidate()
        displayLibraryTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false) { [weak self] _ in
            self?.loadLibraryNativeAd()
        }
    }
    ///搜索原生存储时长
    private func refreshLibraryDate(_ date:Date?) -> Bool {
        guard let date = date else {return false}
        return Date().timeIntervalSince(date) < refreshLibraryTimes
    }
    //异步加载曲库插页广告
    func loadLibraryInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (LibraryINSERTID.count-1) else {
            print("曲库插页广告组已经全部加载失败，停止继续加载")
            //开始加载全局插页
            loadGlobalInterstitialAd { status in
                completion(status)
            }
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingLibraryInterstitialAd || isLibraryInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingLibraryInterstitialAd = true
        let item = LibraryINSERTID[level]
        //加载曲库插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载曲库插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingLibraryInterstitialAd = false
                    loadLibraryInterstitialAd(level+1, completion: completion)
                } else {
                    self.libraryInterstitialAd = ad
                    self.isLoadingLibraryInterstitialAd = false
                    //实现代理
                    self.libraryInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadLibraryInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///曲库插页广告展示
    func showLibraryInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingLibraryInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果曲库广告尚不可用但应该显示，则加载新广告。
        if !isLibraryInterstitialAdAvailable() {
            loadLibraryInterstitialAd { [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showLibraryInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        MP_AnalyticsManager.shared.listclk_ads_chanceAction()
        //当曲库插页广告确定有值后展示
        if let ad = libraryInterstitialAd {

            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingLibraryInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else if let ad = globalInterstitialAd {
            //加载全局插页广告

            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }else {
            MP_AnalyticsManager.shared.listclk_ads_showFailureAction("Ad loading failed")
        }
    }
    //查询是否有曲库插页广告
    func isLibraryInterstitialAdAvailable() -> Bool {
        return libraryInterstitialAd != nil && wasAdexpirationTime(loadLibraryInterstitialAdTime)
    }
    
    
    //MARK: - 全局
    //全局备用插页ID
    private var GlobalINSERTID:[MPPositive_AdModelModel] = []
    ///全局插页广告
    private var globalInterstitialAd:GADInterstitialAd?
    ///是否正在加载全局插页广告
    private var isLoadingGlobalInterstitialAd:Bool = false
    ///是否正在展示全局插页广告
    var isShowingGlobalInterstitialAd:Bool = false
    ///全局插页加载时间
    private var loadGlobalInterstitialAdTime:Date?
    ///全局广告处理闭包
    var completeGlobalInterstitialAdBlock:(() -> Void)?
    //异步加载全局插页广告
    func loadGlobalInterstitialAd(_ level:Int = 0, completion: @escaping (Bool) -> Void) {
        guard openAdStatus else {return}
        guard level <= (GlobalINSERTID.count-1) else {
            print("全局插页广告组已经全部加载失败，停止继续加载")
            completion(false)
            return
        }
        // 检测当前是否有广告或者有广告正在加载
        if isLoadingGlobalInterstitialAd || isGlobalInterstitialAdAvailable() {
            // 有广告或有广告在加载
            completion(false)
            return
        }
        isLoadingGlobalInterstitialAd = true
        let item = GlobalINSERTID[level]
        //加载全局插页广告
        GADInterstitialAd.load(withAdUnitID: item.identifier, request: GADRequest()) { ad, error in
            DispatchQueue.main.async { [weak self] in
                guard let self = self else { return }
                if let error = error {
                    print("加载全局插页广告失败，失败原因: \(error.localizedDescription)，已下调广告ID等级，重新加载")
                    self.isLoadingGlobalInterstitialAd = false
                    loadGlobalInterstitialAd(level+1, completion: completion)
                } else {
                    self.globalInterstitialAd = ad
                    self.isLoadingGlobalInterstitialAd = false
                    //实现代理
                    self.globalInterstitialAd?.fullScreenContentDelegate = self
                    //更新加载时间
                    self.loadGlobalInterstitialAdTime = Date()
                    completion(true)
                }
            }
        }
    }
    ///全局插页广告展示
    func showGlobalInterstitialAdIfAvailable(completion:((GADInterstitialAd) -> Void)?) {
        guard openAdStatus else {return}
        // 如果应用插页广告或者开屏广告已经正在展示，则不再展示该广告。
        guard !interstitialSwitch, !isShowingGlobalInterstitialAd else { return }
        //检索是否存在插页间隔时间
        if let date = interstitialDate {
            if isShowInterstitialADAvailable(date) == false {
                //未超过插页间隔时长
                print("距上一次展示插页广告时长未超过要求，此次插页广告展示滞后")
                return
            }
        }
        // 如果全局广告尚不可用但应该显示，则加载新广告。
        if !isGlobalInterstitialAdAvailable() {
            loadGlobalInterstitialAd { [weak self] success in
                guard let self = self else { return }
                if success {
                    self.showGlobalInterstitialAdIfAvailable(completion: completion)
                }
            }
            return
        }
        //当全局插页广告确定有值后展示
        if let ad = globalInterstitialAd {
            //传递加载完成事件
            if let block = completion {
                block(ad)
            }else {
                isShowingGlobalInterstitialAd = true
                interstitialSwitch = true
                ad.present(fromRootViewController: nil)
            }
        }
    }
    //查询是否有全局插页广告
    func isGlobalInterstitialAdAvailable() -> Bool {
        return globalInterstitialAd != nil && wasAdexpirationTime(loadGlobalInterstitialAdTime)
    }
    //MARK: - 广告音频代理 GADAudioVideoManagerDelegate
    //广告将会播放视频
    func audioVideoManagerWillPlayVideo(_ audioVideoManager: GADAudioVideoManager) {
        print("广告将会播放视频")
    }
    //广告将会暂停播放所有视频
    func audioVideoManagerDidPauseAllVideo(_ audioVideoManager: GADAudioVideoManager) {
        print("广告暂停播放视频")
    }
    //广告将要播放音频
    func audioVideoManagerWillPlayAudio(_ audioVideoManager: GADAudioVideoManager) {
        accessAppdelegate.setAudioStop()
    }
    //广告停止播放音频
    func audioVideoManagerDidStopPlayingAudio(_ audioVideoManager: GADAudioVideoManager) {
        DispatchQueue.main.asyncAfter(deadline: .now()+0.1) {
            accessAppdelegate.setAudioResume()
        }
    }
    //MARK: - 覆盖型广告代理 GADFullScreenContentDelegate
    //覆盖型广告将要将要展示
    func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        if ad === appOpenAd || ad === appInterstitialAd {//开屏广告
            print("当前展示的广告是开屏广告，广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? ""))")
            //当前是热启动还是冷启动
            if OpenICEID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
                //冷启动,检索是插页还是开屏
                if let openAd = appOpenAd {
                    //上传广告收益
                    openAd.paidEventHandler = { adValue in
                        MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
                    }
                }else if let openAd = appInterstitialAd {
                    //上传广告收益
                    openAd.paidEventHandler = { adValue in
                        MP_AnalyticsManager.shared.cold_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
                    }
                }
            }else if OpenHOSTID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
                //热启动,检索是插页还是开屏
                if let openAd = appOpenAd {
                    //上传广告收益
                    openAd.paidEventHandler = { adValue in
                        MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
                    }
                }else if let openAd = appInterstitialAd {
                    //上传广告收益
                    openAd.paidEventHandler = { adValue in
                        MP_AnalyticsManager.shared.hot_ads_showSuccessAction(openAd.responseInfo, adValue: adValue)
                    }
                }
            }
        }else if ad === searchInterstitialAd {//搜索插页广告
            print("当前展示的广告是搜索插页广告，广告ID--\(searchInterstitialAd?.adUnitID ?? "")")
            searchInterstitialAd?.paidEventHandler = { adValue in
                if let response = self.searchInterstitialAd?.responseInfo {
                    MP_AnalyticsManager.shared.search_ads_showSuccessAction(response, adValue: adValue)
                }
            }
        }else if ad === playInterstitialAd {//播放插页广告
            print("当前展示的广告是播放插页广告，广告ID--\(playInterstitialAd?.adUnitID ?? "")")
            playInterstitialAd?.paidEventHandler = { adValue in
                if let response = self.playInterstitialAd?.responseInfo {
                    MP_AnalyticsManager.shared.play_ads_showSuccessAction(response, adValue: adValue)
                }
            }
        }else if ad === switchInterstitialAd {//切歌插页广告
            print("当前展示的广告是切歌插页广告，广告ID--\(switchInterstitialAd?.adUnitID ?? "")")
            switchInterstitialAd?.paidEventHandler = { adValue in
                if let response = self.switchInterstitialAd?.responseInfo {
                    MP_AnalyticsManager.shared.cut_ads_showSuccessAction(response, adValue: adValue)
                }
            }
        }else if ad === loadInterstitialAd {//下载插页广告
            print("当前展示的广告是下载插页广告，广告ID--\(loadInterstitialAd?.adUnitID ?? "")")
            loadInterstitialAd?.paidEventHandler = { adValue in
                if let response = self.loadInterstitialAd?.responseInfo {
                    MP_AnalyticsManager.shared.dl_ads_showSuccessAction(response, adValue: adValue)
                }
            }
        }else if ad === libraryInterstitialAd {//曲库插页广告
            print("当前展示的广告是曲库插页广告，广告ID--\(libraryInterstitialAd?.adUnitID ?? "")")
            libraryInterstitialAd?.paidEventHandler = { adValue in
                if let response = self.libraryInterstitialAd?.responseInfo {
                    MP_AnalyticsManager.shared.listclk_ads_showSuccessAction(response, adValue: adValue)
                }
            }
        }else if ad === globalInterstitialAd {//全局插页广告
            print("当前展示的广告是全局插页广告，广告ID--\(globalInterstitialAd?.adUnitID ?? "")")
        }
    }
    //覆盖型广告已经消失
    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        //更新插页广告展示时间
        interstitialDate = Date()
        if ad === appOpenAd || ad === appInterstitialAd {//开屏广告
            print("当前消失的广告是开屏广告，广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? ""))")
            //执行开屏广告完成事件包
            if completeOpenAdBlock != nil {
                completeOpenAdBlock!()
            }
        }else if ad === searchInterstitialAd {//搜索插页广告
            print("当前消失的广告是搜索插页广告，广告ID--\(searchInterstitialAd?.adUnitID ?? "")")
            //执行搜索插页广告完成事件包
            if completeSearchInterstitialAdBlock != nil {
                completeSearchInterstitialAdBlock!()
            }
        }else if ad === playInterstitialAd {//播放插页广告
            print("当前消失的广告是播放插页广告，广告ID--\(playInterstitialAd?.adUnitID ?? "")")
            //执行播放插页广告完成事件包
            if completePlayInterstitialAdBlock != nil {
                completePlayInterstitialAdBlock!()
            }
        }else if ad === switchInterstitialAd {//播放插页广告
            print("当前消失的广告是切歌插页广告，广告ID--\(switchInterstitialAd?.adUnitID ?? "")")
            //执行播放插页广告完成事件包
            if completeSwitchInterstitialAdBlock != nil {
                completeSwitchInterstitialAdBlock!()
            }
        }else if ad === loadInterstitialAd {//下载插页广告
            print("当前消失的广告是下载插页广告，广告ID--\(loadInterstitialAd?.adUnitID ?? "")")
            //执行播放插页广告完成事件包
            if completeLoadInterstitialAdBlock != nil {
                completeLoadInterstitialAdBlock!()
            }
        }else if ad === libraryInterstitialAd {//曲库插页广告
            print("当前消失的广告是曲库插页广告，广告ID--\(libraryInterstitialAd?.adUnitID ?? "")")
            //执行搜索插页广告完成事件包
            if completeLibraryInterstitialAdBlock != nil {
                completeLibraryInterstitialAdBlock!()
            }
        }else if ad === globalInterstitialAd {///全局插页广告
            print("当前消失的广告是全局插页广告，广告ID--\(globalInterstitialAd?.adUnitID ?? "")")
            //执行搜索插页广告完成事件包
            if completeGlobalInterstitialAdBlock != nil {
                completeGlobalInterstitialAdBlock!()
            }
        }
        
    }
    //覆盖型广告加载出错
    func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
        //更新插页广告展示时间
        interstitialDate = Date()
        if ad === appOpenAd || ad === appInterstitialAd {//应用开屏广告
            print("开屏广告展示时出错，广告ID--\(appOpenAd != nil ? (appOpenAd?.adUnitID ?? ""):(appInterstitialAd?.adUnitID ?? ""))，具体错误原因:\(error.localizedDescription)")
            //判断是冷启动还是热启动
            if OpenICEID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
                MP_AnalyticsManager.shared.cold_ads_showFailureAction(error.localizedDescription)
            }else if OpenHOSTID.contains(where: {($0.identifier == (appOpenAd?.adUnitID ?? "") || $0.identifier == (appInterstitialAd?.adUnitID ?? ""))}) {
                MP_AnalyticsManager.shared.hot_ads_showFailureAction(error.localizedDescription)
            }
            if completeOpenAdBlock != nil {
                completeOpenAdBlock!()
            }
        }else if ad === searchInterstitialAd {//搜索插页广告
            print("搜索插页广告展示时出错，广告ID--\(searchInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            MP_AnalyticsManager.shared.search_ads_showFailureAction(error.localizedDescription)
            if completeSearchInterstitialAdBlock != nil {
                completeSearchInterstitialAdBlock!()
            }
        }else if ad === playInterstitialAd {//播放插页广告
            print("播放插页广告展示时出错，广告ID--\(playInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            MP_AnalyticsManager.shared.play_ads_showFailureAction(error.localizedDescription)
            //执行播放插页广告完成事件包
            if completePlayInterstitialAdBlock != nil {
                completePlayInterstitialAdBlock!()
            }
        }else if ad === switchInterstitialAd {//切歌插页广告
            print("切歌插页广告展示时出错，广告ID--\(switchInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            MP_AnalyticsManager.shared.cut_ads_showFailureAction(error.localizedDescription)
            //执行播放插页广告完成事件包
            if completeSwitchInterstitialAdBlock != nil {
                completeSwitchInterstitialAdBlock!()
            }
        }else if ad === loadInterstitialAd {//下载插页广告
            print("下载插页广告展示时出错，广告ID--\(loadInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            MP_AnalyticsManager.shared.dl_ads_showFailureAction(error.localizedDescription)
            //执行下载插页广告完成事件包
            if completeLoadInterstitialAdBlock != nil {
                completeLoadInterstitialAdBlock!()
            }
        }else if ad === libraryInterstitialAd {//搜索插页广告
            print("曲库插页广告展示时出错，广告ID--\(libraryInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            MP_AnalyticsManager.shared.listclk_ads_showFailureAction(error.localizedDescription)
            if completeLibraryInterstitialAdBlock != nil {
                completeLibraryInterstitialAdBlock!()
            }
        }else if ad === globalInterstitialAd {//全局插页广告
            print("全局插页广告展示时出错，广告ID--\(globalInterstitialAd?.adUnitID ?? "")，具体错误原因:\(error.localizedDescription)")
            if completeGlobalInterstitialAdBlock != nil {
                completeGlobalInterstitialAdBlock!()
            }
        }

    }
    //MARK: - GADNativeAdLoaderDelegate
    // 原生广告已加载，可以展示。
    func adLoader(_ adLoader: GADAdLoader, didReceive nativeAd: GADNativeAd) {
        if nativeAd.mediaContent.hasVideoContent {
//            //判断这个原生广告是什么类型
//            nativeAd.mediaContent.videoController.setMute(true)
//            nativeAd.mediaContent.videoController.delegate = self
        }
        if adLoader == searchAdLoader {//加载的是搜索原生广告
            print("搜索原生已经加载完毕")
            self.searchNativeAd = nativeAd
            self.expirationSearchDate = Date()
            if let block = self.onSearchNativeAdBlock {
                block()
            }
        }else if adLoader == libraryAdLoader {//加载的是曲库原生广告
            print("曲库原生已经加载完毕")
            guard libraryNativeAds != nil else {
                return
            }
            if (libraryNativeAds?.count ?? 0) < 2  {
                //添加广告
                libraryNativeAds?.append(nativeAd)
            }else {
                //已经有一批广告了，销毁掉
                libraryNativeAds = []
                libraryNativeAds?.append(nativeAd)
            }
            //判断是否加载结束
            if (libraryNativeAds?.count ?? 0) == 2 {
                self.expirationLibraryDate = Date()
                if let block = self.onLibraryNativeAdBlock {
                    block()
                }
            }
        }
    }
    // 原生广告加载错误
    func adLoader(_ adLoader: GADAdLoader, didFailToReceiveAdWithError error: any Error) {
        if adLoader == searchAdLoader {//加载的是搜索原生广告
            print("加载搜索原生广告发生错误，错误详情:\(error.localizedDescription)")
            DispatchQueue.main.asyncAfter(deadline: .now() + 300) {
                [weak self] in
                guard let self = self else {return}
                loadSearchNativeAd()
            }
        }else if adLoader == libraryAdLoader {//加载的是曲库原生广告
            print("加载曲库原生广告发生错误，错误详情:\(error.localizedDescription)")
            DispatchQueue.main.asyncAfter(deadline: .now() + 300) {
                [weak self] in
                guard let self = self else {return}
                loadLibraryNativeAd()
            }
        }
    }
    // 原生广告已展示。
    func nativeAdDidRecordImpression(_ nativeAd: GADNativeAd) {
        print("原生广告刷新")
    }
    // 原生广告被点击了。
    func nativeAdDidRecordClick(_ nativeAd: GADNativeAd) {
        print("原生广告被点击")
    }
    // 原生广告将呈现全屏视图。
    func nativeAdWillPresentScreen(_ nativeAd: GADNativeAd) {
        print("原生广告将弹出一个新视图")
    }
    // 原生广告将会关闭全屏视图。
    func nativeAdWillDismissScreen(_ nativeAd: GADNativeAd) {
        print("原生广告视图将要关闭")
    }
    // 原生广告关闭了全屏视图。
    func nativeAdDidDismissScreen(_ nativeAd: GADNativeAd) {
        print("原生广告视图已经关闭")
    }
    // 原生广告将导致应用处于非活动状态并且打开新的应用。
    func nativeAdWillLeaveApplication(_ nativeAd: GADNativeAd) {
      
    }
    //MARK: - GADVideoControllerDelegate
    // 开始播放原生视频广告
    func videoControllerDidPlayVideo(_ videoController: GADVideoController) {
        //强制切回控制中心权限
        
    }
    // 暂停原生视频广告
    func videoControllerDidPauseVideo(_ videoController: GADVideoController) {
        //强制切回控制中心权限
        
    }
    // 停止播放视频广告
    func videoControllerDidEndVideoPlayback(_ videoController: GADVideoController) {
        //强制切回控制中心权限
        
    }
}
