//
//  KMAdvertisementManager.swift
//  KMAdvertisement
//
//  Created by lizhe on 2022/11/23.
// 广告管理

@objcMembers open class KMAdvertisementManager: NSObject {
    //单例
    @objc public static let manager = KMAdvertisementManager()
    @objc public var configuration: KMAdvertisementConfig = KMAdvertisementConfig()
    
    var info: KMAdvertisementInfo = KMAdvertisementInfo()
    var infoDict: NSDictionary = NSDictionary()
    
    /**
     @abstract 测试模式,默认为false
      */
    @objc public var debug: Bool = false
    
    /**
     @abstract 初始化数据
     @param appID 产品名称
     @param subscribeType 订阅状态,可单独在configuration设置
     @param platform 平台
     @return
      */
    @objc public func initConfig(appName: KMAdvertisementAppNameType,
                                 subscribeType:KMAdvertisementSubscribeType,
                                 platform: KMAdvertisementPlatformType) {
        configuration.initParameters(appName: appName, subscribeType: subscribeType, platform: platform)
    }
    
    private class InternalImplementation {
            fileprivate var privateProperty: String = "Hidden"
            fileprivate func internalMethod() {
                // 实现细节
            }
        }
        
        private let internalImplementation = InternalImplementation()
        
        public func publicMethod() {
            // 使用内部实现
            internalImplementation.internalMethod()
        }
}

extension KMAdvertisementManager {
    //MARK: request
    /**
     @abstract 获取数据
     @param data 传入参数 类型为KMAdvertisementModel
     @return
      */
    @objc public func fetchData(completion: @escaping (_ data: KMAdvertisementInfo?, _ error:Error?) -> Void) -> Void {
        self.fetchDataWithResponseObject { data, responseObject, error in
            if completion != nil {
                completion(data, error)
            }
        }
    }
    
    @objc public func fetchDataWithResponseObject(completion:@escaping (_ data: KMAdvertisementInfo?, _ responseObject: AnyObject? , _ error:Error?) -> Void) -> Void {
        print("开始获取数据")
        var version: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString").debugDescription
        if (version.count == 0) {
            version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion").debugDescription
            version = version.replacingOccurrences(of: ".", with: "")
        }
        
        let urlString = configuration.activityBaseURL() + "/api/advertise-new"
        let params: [String:Any] = ["app_name": configuration.appName.string(),
                                    "app_version": version]
        
        //先拿缓存数据 再请求新数据
        let cacheData = KMAdvertisementCache.default.readData()
        if cacheData.count != 0 {
            for model in cacheData {
                let jsonString: String = (model["detail"] as? String) ?? ""
                let jsonData: Data = jsonString.data(using: .utf8)!
                let dict = try?JSONSerialization.jsonObject(with: jsonData)
                infoDict = dict as! NSDictionary
            }
            self.parseData(data: cacheData, isNeedLocalComparison: true) { result in
                if result.count != 0 {
                    info = result.first!
                    completion(result.first, nil, nil)
                }
            }
        }
        
        unowned let weakSelf = self
        KMAdvertisementRequestServer.requestServer.request(urlString: urlString, method: "GET", params: params) { [self] task, responseObject, error in
            print("正在获取数据")
            if (error == nil && responseObject != nil) {
                let array = responseObject?["list"] ?? []
                if array != nil {
                    //解析数据
                    print("开始解析数据")
                    for model in array as! [NSDictionary] {
                        let jsonString: String = (model["detail"] as? String) ?? ""
                        let jsonData: Data = jsonString.data(using: .utf8)!
                        let dict = try?JSONSerialization.jsonObject(with: jsonData)
                        infoDict = dict as! NSDictionary
                    }
                    
                    weakSelf.parseData(data: array as! [NSDictionary], isNeedLocalComparison: true) { data in
                        print("数据处理完毕")
                        if data.count != 0 {
                            info =  data.first!
                            completion(data.first, responseObject, nil)
                        }
                    }
                } else {
                    print("解析数据失败array")
                    completion(nil, responseObject, error)
                }
            } else {
                print("解析数据失败数据不存在")
                completion(nil, responseObject, error)
            }
        }
    }
}


extension KMAdvertisementManager {
    //MARK: data
    /**
     @abstract 解析数据
     @param data 传入参数 NSDictionary
     @param isNeedLocalComparison 是否需要对比本地版本,如果不一样将会刷新
     @return KMAdvertisementModel
     */
    public func parseData(data: [NSDictionary], isNeedLocalComparison: Bool ,completion:(_ result: [KMAdvertisementInfo]) -> Void) -> Void {
        //获取缓存数据
        var isNeedSave = false
        let cacheData = KMAdvertisementCache.default.readData()
        
        var resultArray:[KMAdvertisementInfo] = []
        for model in data {
            if (isNeedLocalComparison) {
                if (self.allowLoadData(data: model)) {
                    let jsonString: String = (model["detail"] as? String) ?? ""
                    let jsonData: Data = jsonString.data(using: .utf8)!
                    let dict = try?JSONSerialization.jsonObject(with: jsonData)
                    let decoder = JSONDecoder()
                    //                decoder.dataDecodingStrategy = .base64
                    //                decoder.keyDecodingStrategy = .convertFromSnakeCase //带下划线命名
                    
                    decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "+∞", negativeInfinity: "-∞", nan: "NaN")
#if DEBUG
                    print(dict)
                    //MARK: 测试使用
                    var advertisementModel = try! decoder.decode(KMAdvertisementInfo.self, from: jsonData)
                    if (self.allowLoadContentData(data: advertisementModel)) {
                        resultArray.append(self.allowLoadItemData(advertisementModel))
                        isNeedSave = true
                    }
#else
                    //            MARK: 此处try 使用 ? ,如果数据出问题 advertisementModel将无参数, 测试时使用!
                    var advertisementModel = try? decoder.decode(KMAdvertisementInfo.self, from: jsonData)
                    if (advertisementModel != nil) {
                        if (self.allowLoadContentData(data: advertisementModel!)) {
                            resultArray.append(self.allowLoadItemData(advertisementModel!))
                            isNeedSave = true
                        }
                    }
#endif
                }
            }
        }
        
        if isNeedSave && isNeedLocalComparison {
            KMAdvertisementCache.default.saveData(data: data)
            print("已更新本地数据")
        } else {
            print("不需要更新本地数据")
        }
        
        completion(resultArray)
    }
    
    func allowLoadData(data: NSDictionary) -> Bool {
        var result = false
        
        let status = (data["status"] as? Int) ?? 0
        let app_name: String = data["app_name"] as? String ?? ""
        
        if (status == 1 &&
            app_name == configuration.appName.string()) {
            result = true
        }
        return result
        
    }
    
    func allowLoadContentData(data: KMAdvertisementInfo) -> Bool {
        var result = true
        return result
    }
    
    //    func allowLoadContentData(data: KMAdvertisementModel) -> Bool {
    //        var result = false
    //
    //        let time: NSInteger = NSInteger(KMAdvertisementTimeStampConversion.getCurrentTimeInterval())!
    //        let startTime: NSInteger = NSInteger(data.startTime!)!
    //        let endTime: NSInteger = NSInteger(data.endTime!)!
    //        let platform = configuration.platform
    //        let subscribeType = configuration.subscribeType
    //        let version = data.version ?? "1.0"
    //        let localVersion = self.getLocalVersion()
    //        let hidden = data.hidden ?? false
    //
    //        if (time >= startTime &&
    //            time <= endTime &&
    //            platform == data.platform &&
    //            self.compareVersion(nowVersion:localVersion, newVersion: version) &&
    //            (subscribeType == data.subscribeType || data.subscribeType == .all) &&
    //            !hidden) {
    //            result = true
    //        }
    //        return result
    //    }
    
    //过滤item是否显示
    func allowLoadItemData(_ data: KMAdvertisementInfo) -> KMAdvertisementInfo {
        let advertisement = data.advertisement
        advertisement?.content = self.canShow(data: (advertisement?.content)!)
        data.advertisement = advertisement
        
        let recommondContent = data.recommondContent
        let recommondContentOther = recommondContent?.recommondContentOther
        let recommondContentPDFPro = recommondContent?.recommondContentPDFPro
        
        recommondContentOther?.content = self.canShow(data: (recommondContentOther?.content)!)
        recommondContentPDFPro?.content = self.canShow(data: (recommondContentPDFPro?.content)!)
        
        recommondContent?.recommondContentOther = recommondContentOther
        recommondContent?.recommondContentPDFPro = recommondContentPDFPro
        data.recommondContent = recommondContent
        
        return data;
    }
    
    func canShow(data: [KMAdvertisementItemInfo]) -> [KMAdvertisementItemInfo] {
        var dataArray: [KMAdvertisementItemInfo] = []
        for item in data {
            let currentTime = Int(NSDate.init().timeIntervalSince1970 * 1000)
            if item.show == "1" &&
                currentTime > Int(item.startTime ?? "0") ?? currentTime &&
                currentTime < Int(item.endTime ?? "0") ?? currentTime {
                
                var canAdd = true
                if item.subscriptionType == "1" {
                    if (IAPProductsManager.default().isAvailableAllFunction()) {
                        canAdd = false
                    }
                } else if item.subscriptionType == "2" {
                    if (IAPProductsManager.default().isAvailableAllFunction() == false) {
                        canAdd = false
                    }
                }
            
                if canAdd {
                    dataArray.append(item)
                }
            }
        }
        
        return dataArray
    }
    
//    + (BOOL)checkAdvertisementValid:(KMRecommondInfo *)info {
//    #if DEBUG
//        [[NSUserDefaults standardUserDefaults] removeObjectForKey:info.versionKey];
//    #endif
//        if ([[NSUserDefaults standardUserDefaults] objectForKey:info.versionKey]) {
//            return NO;
//        }
//        if (!info.show) {
//            return NO;
//        }
//        if (info.showType == KMRecommondShowType_Lite) {
//            if ([[IAPProductsManager defaultManager] isAvailableAllFunction]) {
//                return NO;
//            }
//        } else if (info.showType == KMRecommondShowType_Pro) {
//            if (![[IAPProductsManager defaultManager] isAvailableAllFunction]) {
//                return NO;
//            }
//        }
//        return YES;
//    }
    
//    func allowLoadItemData(_ data: KMAdvertisementModel) -> KMAdvertisementModel {
//        //获取缓存数据
//        if (UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") == nil) {
//            UserDefaults.standard.set([], forKey: "KMAdvertisementShowScroll_iOS")
//        }
//        let cacheArray: [String] = UserDefaults.standard.object(forKey: "KMAdvertisementShowScroll_iOS") as! [String]
//        
//        let model = data
//        var sections: [KMAdvertisementModelSection] = []
//        for section in data.content! {
//            var items: [KMAdvertisementModelItem] = []
//            for item in section.content! {
//                let timeString = KMAdvertisementTimeStampConversion.getCurrentTimeInterval()
//                let time: NSInteger = NSInteger(timeString)!
//                let startTime: NSInteger = NSInteger(item.startTime ?? timeString)!
//                let endTime: NSInteger = NSInteger(item.endTime ?? timeString)!
//                let hidden = item.hidden ?? false
//
////                print(hidden ? "隐藏" : "显示")
//                if (!hidden &&
//                    time >= startTime &&
//                    time <= endTime &&
//                    !cacheArray.contains(item.productID ?? "")) {
//                    items.append(item)
//                }
//            }
//            section.content = items
//            sections.append(section)
//        }
//        model.content = sections
//        return model
//    }
    
    //获取本地版本号
    func getLocalVersion() -> String {
        var localVersion = ""
        if let v: String = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String {
            localVersion = v
        }
        return localVersion
    }
    
    func compareVersion(nowVersion: String, newVersion: String) -> Bool {
        let nowArray = nowVersion.split(separator: ".")
        let newArray = newVersion.split(separator: ".")
        let big = nowArray.count > newArray.count ? newArray.count : nowArray.count
        if big != 0 {
            for index in 0...big - 1 {
                let first = nowArray[index]
                let second = newArray[index]
                if Int(first)! < Int(second)!  {
                    return true
                }
                if index == big - 1 {
                    if Int(first)! <= Int(second)!  {
                        return true
                    }
                }
            }
        } else {
            return true
        }
        return false
    }
}

extension KMAdvertisementManager {
    static func checkAdvertisementValid(_ info: KMAdvertisementItemInfo) -> Bool {
        #if DEBUG
        UserDefaults.standard.removeObject(forKey: info.version ?? "")
        #endif
        
        if UserDefaults.standard.object(forKey: info.version ?? "") != nil {
            return false
        }
        
        if (info.show == nil) {
            return false
        }
        
        let currentTime = Int(NSDate.init().timeIntervalSince1970 * 1000)
        if currentTime > Int(info.startTime ?? "0") ?? currentTime &&
            currentTime < Int(info.endTime ?? "0") ?? currentTime {
           
        } else {
            return false
        }
        
        
        if info.subscriptionType == "1" {
            if IAPProductsManager.default().isAvailableAllFunction() {
                return false
            }
        } else if info.subscriptionType == "2" {
            if !IAPProductsManager.default().isAvailableAllFunction() {
                return true
            }
        }
        
        return true
    }
}