//
//  YL_NetWorkManager.swift
//  wallpaper_project
//  Created by 忆海16 on 2024/9/29.
//

import Foundation
import UIKit
import AdSupport
import CoreTelephony
import Network
import SystemConfiguration
import AVFoundation
import OpenGLES
import AppTrackingTransparency
import CommonCrypto


/// <#Description#>
class YL_NetWorkManager{
    static var kBaseUrl = YL_NetWorkManager.bFaceLocalUrl()
    
    static var kURL_AD_Start = "/top_selection/save_app_start_log"
    static var kURL_AD_Load = "/top_selection/save_ad_load_log"
    static var kURL_AD_Show = "/top_selection/save_ad_show_log"
    static var kURL_save_logs = "/ios/top_selection/save_iphone_logs"
    
    var ipLoadTime: DispatchTime?
    
    static var  kLocalBaseUrl = BbbAdManager.config.adbrush_local_url
    
    
    static var kLocalUrlStr: (String) -> String {
        return { path in
            return "\(self.kLocalBaseUrl)/\(path)"
        }
    }
    
    
    static func bFaceLocalUrl() -> String {
        
        return BbbAdManager.config.adbrush_base_url
        
    }
    
    
    
    typealias LuxNetManagerCallback = (Error?, Bool, [String: Any]?) -> Void
    
    
    
    static func uploadData(mdic: [String: Any], urlPath: String, callback: @escaping (Error?, Bool, [String: Any]?) -> Void) {
        guard let url = URL(string: urlPath) else {
            print("Invalid URL")
            return
        }
        
        print("---------mdic \(mdic)")
        
        print("---------urlPath\(urlPath)")
        
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        
        do {
            let data = try JSONSerialization.data(withJSONObject: mdic, options: [])
            request.httpBody = data
        } catch {
            print("Error serializing JSON: \(error.localizedDescription)")
            
            
            DispatchQueue.main.async {
                NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: [
                    "text":"Error serializing JSON: \(error.localizedDescription)"
                ])
            }
            
            return
        }
        
        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                callback(error, false, nil)
                print("Network error: \(error.localizedDescription)")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: [
                        "text":"Network error: \(error.localizedDescription)"
                    ])
                }
            } else {
                guard let data = data else {
                    callback(nil, false, nil)
                    print("No data received")
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: [
                            "text":"No data received"
                        ])
                    }
                    return
                }
                
                do {
                    if let result = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                        print("Server response: \(result)")
                        callback(nil, true, result)
                        
                        DispatchQueue.main.async {
                            NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: [
                                "text":"Server response: \(result)"
                            ])
                        }
                        
                    }
                } catch {
                    callback(error, false, nil)
                    
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: [
                            "text":"Error parsing response JSON: \(error.localizedDescription)"
                        ])
                    }
                    
                    
                    
                    print("Error parsing response JSON: \(error.localizedDescription)")
                }
            }
        }
        
        task.resume()
    }
    
    
    //    请求远程IP
    func requestRemoteIp() {
        ipLoadTime = DispatchTime.now()
        
        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "获取ip中..."])
        
        guard let url = URL(string: "https://openapi.lux-ad.com/app/common/getIPInfo") else { return }
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("解析ip失败....")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "解析ip失败...."])
                }
                return
            }
            
            guard let data = data,
                  let result = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
                  let ip = result["data"] as? [String: Any],
                  let ipAddress = ip["ip"] as? String,
                  let isoCode = ip["isoCode"] as? String else {
                print("解析ip失败....")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "解析ip失败...."])
                }
                return
            }
            
            if !ipAddress.isEmpty {
                UserDefaults.standard.set(ipAddress, forKey: "kIP_key")
                UserDefaults.standard.set(isoCode, forKey: "kIP_key_isoCode")
                UserDefaults.standard.synchronize()
                
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "当前ip: \(ipAddress) \n国家: \(isoCode) "])
                }
                
                if let startTime = self.ipLoadTime {
                    let loadDuration = self.IpcalculateElapsedTime(since: startTime)
                    BbbAdManager.config.ipTime = loadDuration
                }
                
            } else {
                print("解析ip失败....")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "解析ip失败...."])
                }
            }
        }
        task.resume()
    }
    
    
    // 辅助函数以毫秒为单位计算经过的时间
    private func IpcalculateElapsedTime(since startTime: DispatchTime) -> Int {
        let endTime = DispatchTime.now()
        let nanoseconds = endTime.uptimeNanoseconds - startTime.uptimeNanoseconds
        return Int(nanoseconds / 1_000_000) // 转换为毫秒
    }
    
    
    // DeviceId
    
    static func getDeviceId() -> String {
        var adbrushDeviceId = UserDefaults.standard.dictionary(forKey: "bfaceDictKey")?["adbrush_deviceid"] as? String
        if adbrushDeviceId == nil {
            adbrushDeviceId = UIDevice.current.identifierForVendor?.uuidString
            var bfaceDict = UserDefaults.standard.dictionary(forKey: "bfaceDictKey") ?? [:]
            bfaceDict["adbrush_deviceid"] = adbrushDeviceId
            UserDefaults.standard.set(bfaceDict, forKey: "bfaceDictKey")
            UserDefaults.standard.synchronize()
        }
        
        return adbrushDeviceId ?? ""
    }
    
    
    //    本地IP
    static func getLocalIp() -> String {
        var address = "an error occurred when obtaining ip address"
        var interfaces: UnsafeMutablePointer<ifaddrs>? = nil
        
        if getifaddrs(&interfaces) == 0 {
            var tempAddr = interfaces
            
            while tempAddr != nil {
                let addrFamily = tempAddr!.pointee.ifa_addr.pointee.sa_family
                let name = String(cString: tempAddr!.pointee.ifa_name)
                
                if addrFamily == AF_INET && name == "en0" {
                    var ipAddress = sockaddr_in()
                    memcpy(&ipAddress, tempAddr!.pointee.ifa_addr, MemoryLayout<sockaddr_in>.size)
                    address = String(cString: inet_ntoa(ipAddress.sin_addr))
                }
                tempAddr = tempAddr!.pointee.ifa_next
            }
            freeifaddrs(interfaces)
        }
        return address
    }
    
    
    //    包名
    static func getPackageName() -> String {
        return Bundle.main.bundleIdentifier ?? ""
    }
    
    //    版本
    static func getappVersion() -> String {
        
        return Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
        
    }
    
    //    手机型号
    static func getiphone() -> String {
        
        return UIDevice.current.localizedModel
        
    }
    
    // 系统版本
    static func getosVersion() -> String {
        
        return UIDevice.current.systemVersion
        
    }
    
    //    电池电量
    static  func getBatteryLevel() -> Float? {
        return UIDevice.current.batteryLevel
    }
    
    //    是否在充电
    static func isDeviceCharging() -> Bool {
        return UIDevice.current.batteryState == .charging || UIDevice.current.batteryState == .full
    }
    
    //    获取deviceId
    static func getPhoneDeviceId() -> String? {
        return UIDevice.current.identifierForVendor?.uuidString
    }
    
    //    当前的无线接入技术
    static  func getCurrentRadioAccessTechnology() -> String? {
        let networkInfo = CTTelephonyNetworkInfo()
        let radioAccessTechnology = networkInfo.currentRadioAccessTechnology
        return radioAccessTechnology
    }
    
    
    
    //    时间
    static func getCurrentTime() -> String {
        let date = Date() // 获取当前日期和时间
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss" // 设置日期格式
        formatter.locale = Locale(identifier: "en_US_POSIX") // 确保使用 ISO 8601 标准
        return formatter.string(from: date)
    }
    
    //    字体
    static  func getCurrentFont() -> String {
        return "\(UIFont.systemFont(ofSize: UIFont.systemFontSize))"
    }
    
    //    语言
    static  func getlanguageCode() -> String {
        return Locale.current.languageCode ?? ""
    }
    
    
    //GAID
    
    static func getGaid() -> String {
        return ASIdentifierManager.shared().advertisingIdentifier.uuidString
    }
    
    
    //    IDFA
    static func getIdfa() -> String {
        if ASIdentifierManager.shared().isAdvertisingTrackingEnabled {
            let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
            return idfa
        } else {
            return ""
        }
    }
    
    //    monotonicRawClockTimeMillis 单调时钟时间戳
    static  func getMonotonicRawClockTimeMillis() -> UInt64 {
        let time = mach_absolute_time()
        let nanoseconds = Double(time) / Double(NSEC_PER_SEC) // Convert to nanoseconds
        return UInt64(nanoseconds / 1000000) // Convert to milliseconds
    }
    
    //    内核启动时间戳
    static  func getKernelBootTimeMillis() -> Int64? {
        // 定义变量以存储系统启动时间
        var bootTime = timeval()
        var size = MemoryLayout<timeval>.stride
        
        // 获取系统启动时间
        let mib: [Int32] = [CTL_KERN, KERN_BOOTTIME]
        let result = sysctl(UnsafeMutablePointer<Int32>(mutating: mib), 2, &bootTime, &size, nil, 0)
        
        guard result == 0 else {
            print("获取系统启动时间失败")
            return nil
        }
        
        // 系统启动时间（秒 + 微秒）
        let bootTimeInSeconds = Double(bootTime.tv_sec) + Double(bootTime.tv_usec) / 1_000_000
        
        // 当前时间
        let currentTime = Date().timeIntervalSince1970
        
        // 计算内核运行的时间（秒）
        let kernelBootTimeInSeconds = currentTime - bootTimeInSeconds
        
        // 转换为毫秒
        return Int64(kernelBootTimeInSeconds * 1_000)
    }
    
    
    //    获取运营商信息
    static  func getCarrierInfo() -> String {
        var carrierInfo = ""
        let networkInfo = CTTelephonyNetworkInfo()
        let carrier = networkInfo.serviceSubscriberCellularProviders?.first?.value
        if let carrier = carrier {
            carrierInfo = "\(carrier.mobileCountryCode ?? "") \(carrier.mobileNetworkCode ?? "")"
        }
        return carrierInfo
    }
    
    //    获取网络连接类型
    static  func getNetworkType() -> String {
        let monitor = NWPathMonitor()
        let queue = DispatchQueue.global(qos: .background)
        
        var type:String = ""
        
        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                if path.usesInterfaceType(.wifi) {
                    type = "Wi-Fi"
                } else if path.usesInterfaceType(.cellular) {
                    type = "Cellular"
                } else if path.usesInterfaceType(.wiredEthernet) {
                    type = "Wired Ethernet"
                } else if path.usesInterfaceType(.loopback) {
                    type = "Loopback"
                } else {
                    type = "Other"
                }
            } else {
                type = "Unavailable"
            }
            monitor.cancel() // 停止监控，释放资源
        }
        
        monitor.start(queue: queue)
        return type
    }
    
    // 是否连接VPN
    static  func isVPNOn() -> Bool {
        var flag = false
        let version = UIDevice.current.systemVersion
        
        // Check if the system version is >= 9.0
        if let versionDouble = Double(version), versionDouble >= 9.0 {
            // For iOS 9.0 and above
            if let dict = CFNetworkCopySystemProxySettings() as? Unmanaged<CFDictionary> {
                let bridgedDict = dict.takeUnretainedValue() as? [String: Any]
                
                if let scopedSettings = bridgedDict?["__SCOPED__"] as? [String: Any] {
                    for key in scopedSettings.keys {
                        if key.contains("tap") || key.contains("tun") || key.contains("ipsec") || key.contains("ppp") {
                            flag = true
                            break
                        }
                    }
                }
            }
        } else {
            // For iOS versions below 9.0
            var interfaces: UnsafeMutablePointer<ifaddrs>?
            let success = getifaddrs(&interfaces)
            
            if success == 0 {
                var tempAddr = interfaces
                while tempAddr != nil {
                    if let name = String(validatingUTF8: (tempAddr?.pointee.ifa_name)!) {
                        if name.contains("tap") || name.contains("tun") || name.contains("ipsec") || name.contains("ppp") {
                            flag = true
                            break
                        }
                    }
                    tempAddr = tempAddr?.pointee.ifa_next
                }
            }
            
            // Free memory
            freeifaddrs(interfaces)
        }
        
        return flag
    }
    
    
    
    static func appId() -> String {
        return Bundle.main.bundleIdentifier ?? ""
    }
    
    
    //    获取音量
    static func isDeviceMuted() -> Bool {
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setActive(true)
            // 获取当前音量
            let currentVolume = audioSession.outputVolume
            return currentVolume == 0
        } catch {
            print("Error setting audio session active: \(error.localizedDescription)")
            return false
        }
    }
    
    //    追踪状态
    static func getAdvertisingTrackingStatus() -> String {
        if #available(iOS 14, *) {
            switch ATTrackingManager.trackingAuthorizationStatus {
            case .notDetermined:
                return "notDetermined"
            case .restricted:
                return "restricted"
            case .denied:
                return "denied"
            case .authorized:
                return "authorized"
            @unknown default:
                return "unknown"
            }
        } else {
            // iOS 14 以下版本
            let isTrackingEnabled = ASIdentifierManager.shared().isAdvertisingTrackingEnabled
            return isTrackingEnabled ? "authorized" : "denied"
        }
    }
    
    //    是否启用追踪
    static func isAdvertisingTrackingEnabled() -> Bool {
        if #available(iOS 14, *) {
            switch ATTrackingManager.trackingAuthorizationStatus {
            case .authorized:
                return true // 用户允许广告追踪
            default:
                return false // 用户未授权、受限制或拒绝
            }
        } else {
            // iOS 14 以下版本
            return ASIdentifierManager.shared().isAdvertisingTrackingEnabled
        }
    }
    
    //    获取设备总内存
    
    static  func getTotalMemoryInBytes() -> UInt64 {
        return ProcessInfo.processInfo.physicalMemory
    }
    
    static func getTotalMemoryInReadableFormat() -> String {
        let totalMemoryBytes = getTotalMemoryInBytes()
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = [.useGB] // 只显示为 GB
        formatter.countStyle = .memory
        return formatter.string(fromByteCount: Int64(totalMemoryBytes))
    }
    
    
    //    是否是刘海屏
    static func isNotchScreen() -> Bool {
        // 确保在主线程中访问
        if Thread.isMainThread {
            guard let window = UIApplication.shared.windows.first else { return false }
            let topSafeArea = window.safeAreaInsets.top
            return topSafeArea > 20
        } else {
            // 在非主线程中调用时，通过调度回主线程同步获取结果
            return DispatchQueue.main.sync {
                guard let window = UIApplication.shared.windows.first else { return false }
                let topSafeArea = window.safeAreaInsets.top
                return topSafeArea > 20
            }
        }
    }

    
    //    屏幕方向
    
    static func getScreenOrientation() -> String {
        let orientation = UIDevice.current.orientation
        
        switch orientation {
        case .portrait:
            return "portrait"
        case .portraitUpsideDown:
            return "portraitUpsideDown"
        case .landscapeLeft:
            return "landscapeLeft"
        case .landscapeRight:
            return "landscapeRight"
        case .faceUp:
            return "faceUp"
        case .faceDown:
            return "faceDown"
        case .unknown:
            return "unknown"
        @unknown default:
            return "unknown"
        }
    }
    
    //    获取 OpenGL版本
    static  func getOpenGLVersion() -> String {
        // 尝试初始化 OpenGL ES 3.0 上下文
        if let _ = EAGLContext(api: .openGLES3) {
            return "openGLES3"
        }
        // 尝试初始化 OpenGL ES 2.0 上下文
        else if let _ = EAGLContext(api: .openGLES2) {
            return "openGLES2"
        }
        // 如果上述都失败，则返回 OpenGL ES 1.0
        else if let _ = EAGLContext(api: .openGLES1) {
            return "openGLES1"
        } else {
            return "NO OpenGL ES"
        }
    }
    
    //    获取时区偏移量
    static func getTimeZoneOffsetFromUS() -> Int {
        // 获取当前设备的时区
        let currentTimeZone = TimeZone.current
        
        // 获取美国东部时间的时区（美区时区）
        let usTimeZone = TimeZone(identifier: "America/New_York")
        
        // 获取两个时区的偏移量，单位为秒
        let currentOffset = currentTimeZone.secondsFromGMT()
        let usOffset = usTimeZone?.secondsFromGMT() ?? 0
        
        // 计算偏移差，并将结果转为分钟
        let offsetDifferenceInMinutes = (currentOffset - usOffset) / 60
        return offsetDifferenceInMinutes
    }
    
    //    设备键盘类型
    static func getKeyboardLayoutType() -> [String] {
        var keyboardLayouts: [String] = []
        
        // 获取当前设备的语言环境
        let currentLanguage = Locale.current.languageCode ?? ""
        
        // 根据语言环境推测键盘布局类型
        switch currentLanguage {
        case "en":
            // 英语一般使用 QWERTY 布局
            keyboardLayouts.append("QWERTY")
        case "fr":
            // 法语一般使用 AZERTY 布局
            keyboardLayouts.append("AZERTY")
        case "de":
            // 德语一般使用 QWERTZ 布局
            keyboardLayouts.append("QWERTZ")
        case "es":
            // 西班牙语一般使用 QWERTY 布局
            keyboardLayouts.append("QWERTY")
        case "it":
            // 意大利语一般使用 QWERTY 布局
            keyboardLayouts.append("QWERTY")
        case "ja":
            // 日语一般使用日本输入法
            keyboardLayouts.append("Japanese")
        case "zh":
            // 中文一般使用拼音输入法
            keyboardLayouts.append("Pinyin")
        default:
            // 其他语言暂时返回 QWERTY
            keyboardLayouts.append("QWERTY")
        }
        
        return keyboardLayouts
    }
    
    
    //    设备型号修订版
    static func getDeviceHardwareIdentifier() -> String {
        var size: Int = 0  // 使用 Int 类型而不是 UInt32
        sysctlbyname("hw.model", nil, &size, nil, 0)
        
        var model = [CChar](repeating: 0, count: size)
        sysctlbyname("hw.model", &model, &size, nil, 0)
        
        let modelString = String(cString: model)
        return modelString
    }
    
    //    static func mapHardwareIdentifierToModelNumber(_ identifier: String) -> String {
    //        switch identifier {
    //            // iPhone 系列
    //        case "iPhone13,2":
    //            return "A2172" // iPhone 12
    //        case "iPhone13,3":
    //            return "A2341" // iPhone 12 Pro
    //        case "iPhone13,4":
    //            return "A2342" // iPhone 12 Pro Max
    //        case "iPhone13,1":
    //            return "A2176" // iPhone 12 mini
    //        case "iPhone12,1":
    //            return "A2111" // iPhone 11
    //        case "iPhone12,3":
    //            return "A2160" // iPhone 11 Pro
    //        case "iPhone12,5":
    //            return "A2161" // iPhone 11 Pro Max
    //        case "iPhone11,8":
    //            return "A1882" // iPhone XR
    //        case "iPhone11,2":
    //            return "A1920" // iPhone XS
    //        case "iPhone11,6":
    //            return "A1921" // iPhone XS Max
    //        case "iPhone10,3":
    //            return "A1865" // iPhone X
    //        case "iPhone10,6":
    //            return "A1901" // iPhone X
    //        case "iPhone9,1":
    //            return "A1660" // iPhone 7
    //        case "iPhone9,2":
    //            return "A1661" // iPhone 7 Plus
    //        case "iPhone8,1":
    //            return "A1549" // iPhone 6s
    //        case "iPhone8,2":
    //            return "A1586" // iPhone 6s Plus
    //        case "iPhone7,1":
    //            return "A1522" // iPhone 6 Plus
    //        case "iPhone7,2":
    //            return "A1549" // iPhone 6
    //        case "iPhone6,1":
    //            return "A1528" // iPhone 5s
    //        case "iPhone6,2":
    //            return "A1530" // iPhone 5s
    //        case "iPhone5,1":
    //            return "A1428" // iPhone 5
    //        case "iPhone5,2":
    //            return "A1429" // iPhone 5
    //
    //            // iPad 系列
    //        case "iPad8,1":
    //            return "A1893" // iPad Air 3
    //        case "iPad8,2":
    //            return "A1894" // iPad Air 3
    //        case "iPad8,3":
    //            return "A1954" // iPad Pro 10.5"
    //        case "iPad8,4":
    //            return "A1955" // iPad Pro 10.5"
    //        case "iPad8,5":
    //            return "A1701" // iPad Pro 12.9" (2nd generation)
    //        case "iPad8,6":
    //            return "A1709" // iPad Pro 12.9" (2nd generation)
    //        case "iPad8,7":
    //            return "A1673" // iPad Pro 12.9" (3rd generation)
    //        case "iPad8,8":
    //            return "A1674" // iPad Pro 12.9" (3rd generation)
    //
    //            // iPad Mini 系列
    //        case "iPad4,4":
    //            return "A1454" // iPad Mini 2
    //        case "iPad4,5":
    //            return "A1455" // iPad Mini 2
    //        case "iPad4,6":
    //            return "A1456" // iPad Mini 2
    //        case "iPad5,1":
    //            return "A1822" // iPad Mini 4
    //        case "iPad5,2":
    //            return "A1823" // iPad Mini 4
    //
    //            // iPad Pro 系列
    //        case "iPad6,7":
    //            return "A1652" // iPad Pro 12.9" (1st generation)
    //        case "iPad6,8":
    //            return "A1670" // iPad Pro 12.9" (1st generation)
    //        case "iPad7,1":
    //            return "A1674" // iPad Pro 12.9" (2nd generation)
    //        case "iPad7,2":
    //            return "A1673" // iPad Pro 12.9" (2nd generation)
    //
    //            // Apple Watch 系列
    //        case "Watch1,1":
    //            return "A1554" // Apple Watch (1st generation)
    //        case "Watch1,2":
    //            return "A1553" // Apple Watch (1st generation)
    //        case "Watch2,6":
    //            return "A1792" // Apple Watch Series 1
    //        case "Watch2,7":
    //            return "A1791" // Apple Watch Series 1
    //        case "Watch3,1":
    //            return "A1860" // Apple Watch Series 3
    //        case "Watch3,2":
    //            return "A1861" // Apple Watch Series 3
    //        case "Watch3,3":
    //            return "A1889" // Apple Watch Series 3
    //        case "Watch3,4":
    //            return "A1890" // Apple Watch Series 3
    //        case "Watch4,1":
    //            return "A1975" // Apple Watch Series 4
    //        case "Watch4,2":
    //            return "A1976" // Apple Watch Series 4
    //        case "Watch4,3":
    //            return "A1977" // Apple Watch Series 4
    //        case "Watch4,4":
    //            return "A1978" // Apple Watch Series 4
    //
    //            // Apple TV 系列
    //        case "AppleTV5,3":
    //            return "A1469" // Apple TV (4th generation)
    //        case "AppleTV6,2":
    //            return "A1842" // Apple TV 4K (1st generation)
    //        case "AppleTV11,1":
    //            return "A2169" // Apple TV 4K (2nd generation)
    //        default:
    //            return "Unknown model"
    //        }
    //    }
    
    
    
//    static func uploadAD_Load(adid:String,ecpm:Double,network:String,countryCode:String,platformResponseTime:TimeInterval,dsp:String,loadTime:Int){
//        
//        var mdic: [String: Any] = [:]
//        
//        mdic["deviceId"] = starManager.shared.adbrush_deviceid
//        mdic["gaid"] = self.getGaid()
//        mdic["localIp"] = starManager.shared.adbrush_localip
//        
//        //        let remoteIp = UserDefaults.standard.string(forKey: "kIP_key") ?? ""
//        mdic["remoteIp"] = starManager.shared.remoteIp
//        
//        mdic["packageName"] = appId()
//        mdic["adPlatform"] = "MAX"
//        mdic["countryCode"] = countryCode
//        mdic["adId"] = adid
//        mdic["platformResponseTime"] = platformResponseTime
//        mdic["shelfNumber"] = "uploadAD_Load"
//        mdic["ecpm"] = ecpm
//        mdic["getIpResponseTime"] = starManager.shared.ipTime
//        mdic["dsp"] =  dsp
//        mdic["dataId"] = starManager.shared.dataId
//        mdic["linkId"] = starManager.shared.linkId
//        mdic["loadTime"] = loadTime
//        mdic["succeed"] = true
//        mdic["network"] = network
//        mdic["online"] = false
//        mdic["washParam"] = starManager.shared.washParam
//        
//        // Log the JSON data to verify it's correctly formatted
//        do {
//            let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
//            let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
//            print("Uploading AD Show with data: \(jsonString)")
//            
//            DispatchQueue.main.sync {
//                NotificationCenter.default.post(name: NSNotification.Name("adNetwork"), object: nil, userInfo: ["info": "uploadAD_Load:\n\(jsonString)"])
//            }
//            
//            
//            YL_NetWorkManager.uploadData(mdic: mdic, urlPath: "\(kBaseUrl)\(kURL_AD_Load)") { err, state, result in
//                if let error = err {
//                    print("Error: \(error.localizedDescription)")
//                } else {
//                    print("Result: \(result ?? [:])")
//                    DispatchQueue.main.async {
//                        NotificationCenter.default.post(name: NSNotification.Name("adNetwork"), object: nil, userInfo: ["info": "AdID: \(adid) 广告加载成功, ecpm: \(ecpm) 加载时长: 0ms dsp: \( "MAX") network: \(network)"])
//                    }
//                    
//                }
//            }
//            
//            
//        } catch {
//            print("Error serializing JSON: \(error.localizedDescription)")
//        }
//        
//        
//    }
    
    static func uploadAD_Load(
        adid: String,
        ecpm: Double,
        network: String,
        countryCode: String,
        platformResponseTime: TimeInterval,
        dsp: String,
        loadTime: Int,
        retryCount: Int = 3 // 默认重试3次
    ) {
        var mdic: [String: Any] = [:]
        
        mdic["deviceId"] = BbbAdManager.config.adbrush_deviceid
        mdic["gaid"] = self.getGaid()
        mdic["localIp"] = BbbAdManager.config.adbrush_localip
        mdic["remoteIp"] = BbbAdManager.config.remoteIp
        mdic["packageName"] = appId()
        mdic["adPlatform"] = "MAX"
        mdic["countryCode"] = countryCode
        mdic["adId"] = adid
        mdic["platformResponseTime"] = platformResponseTime
        mdic["shelfNumber"] = "uploadAD_Load"
        mdic["ecpm"] = ecpm
        mdic["getIpResponseTime"] = BbbAdManager.config.ipTime
        mdic["dsp"] = dsp
        mdic["dataId"] = BbbAdManager.config.dataId
        mdic["linkId"] = BbbAdManager.config.linkId
        mdic["loadTime"] = loadTime
        mdic["succeed"] = true
        mdic["network"] = network
        mdic["online"] = false
        mdic["washParam"] = BbbAdManager.config.washParam
        
        // Log the JSON data to verify it's correctly formatted
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
            let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
            print("Uploading AD Show with data: \(jsonString)")
            
        
            
            // 上传数据
            YL_NetWorkManager.uploadData(mdic: mdic, urlPath: "\(kBaseUrl)\(kURL_AD_Load)") { err, state, result in
                if let error = err {
                    print("Error: \(error.localizedDescription)")
                    
                    if retryCount > 0 {
                        print("Retrying... Remaining attempts: \(retryCount - 1)")
                        // 延迟1秒后重试
                        DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + 1.0) {
                            uploadAD_Load(
                                adid: adid,
                                ecpm: ecpm,
                                network: network,
                                countryCode: countryCode,
                                platformResponseTime: platformResponseTime,
                                dsp: dsp,
                                loadTime: loadTime,
                                retryCount: retryCount - 1
                            )
                        }
                    } else {
                        print("Failed to upload data after \(3 - retryCount) retries.")
                    }
                } else {
                    print("Result: \(result ?? [:])")
                }
            }
        } catch {
            print("Error serializing JSON: \(error.localizedDescription)")
        }
    }

    
    
    static func uploadAD_Show(adid:String,ecpm:Double,network:String,countryCode:String,platformResponseTime:TimeInterval,dsp:String){
        
        var mdic: [String: Any] = [:]
        
        mdic["deviceId"] = BbbAdManager.config.adbrush_deviceid
        mdic["gaid"] = self.getGaid()
        mdic["localIp"] = BbbAdManager.config.adbrush_localip
        
        //        let remoteIp = UserDefaults.standard.string(forKey: "kIP_key") ?? ""
        mdic["remoteIp"] = BbbAdManager.config.remoteIp
        
        mdic["packageName"] = appId()
        mdic["adPlatform"] = "MAX"
        mdic["countryCode"] = countryCode
        mdic["adId"] = adid
        mdic["platformResponseTime"] = platformResponseTime
        mdic["shelfNumber"] = "uploadAD_Load"
        mdic["ecpm"] = ecpm
        mdic["getIpResponseTime"] = BbbAdManager.config.ipTime
        mdic["dsp"] =  dsp
        mdic["dataId"] = BbbAdManager.config.dataId
        mdic["linkId"] = BbbAdManager.config.linkId
        mdic["loadTime"] = 0
        mdic["succeed"] = true
        mdic["network"] = network
        mdic["online"] = false
        
        do {
            // Log the JSON data to verify it's correctly formatted
            let jsonData = try JSONSerialization.data(withJSONObject: mdic, options: .prettyPrinted)
            let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
            print("Uploading AD Show with data: \(jsonString)")
            YL_NetWorkManager.uploadData(mdic:mdic, urlPath: "\(kBaseUrl)\(kURL_AD_Show)") { (err, state, result) in
                if let error = err {
                    print("Error uploading AD Show: \(error.localizedDescription)")
                } else {
                    print("Upload AD Show response: \(result ?? [:])")
                }
            }
        } catch {
            print("Error serializing JSON: \(error.localizedDescription)")
        }
        
        
    }
    
    
    
    /*
    
    static func showAd(idfa: String,
                       adId: String,
                       ecpm: Double?,
                       ad: Bool) {
        
        var mdic = [String: Any]()
        mdic["appid"] = appId()
        mdic["idfa"] = getIdfa()
        mdic["ecpm"] = ecpm ?? 0
        mdic["ad"] = ad
        mdic["id"] = adId
        
        uploadData(mdic: mdic, urlPath: kLocalUrlStr("adtask/show")) { err, state, result in
            guard let status = result?["status"] as? String,
                  let time = result!["close"] as? NSNumber else {
                
                return
            }
            
            if status == "Success" && ad {
                
                closeAD.removeADVC(byDelayTime: time.intValue)
                //                closeWindows.removeADVCByDelayTime(time.intValue)
            }
            DispatchQueue.main.async {
                
                NotificationCenter.default.post(name: NSNotification.Name("adNetwork"), object: nil, userInfo: ["info": "showAd,已上传展示AD操作,\(time.intValue / 1000)秒后关闭"])
            }
            
            if ad {
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adNetwork"), object: nil, userInfo: [
                        "info": "AdID:\(adId),广告开始展示,展示时长\(time)"
                    ])
                }
            }
        }
    }
     */
    static func convertStringToDictionary(text: String) -> [String:AnyObject]? {
        if let data = text.data(using: String.Encoding.utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: [JSONSerialization.ReadingOptions.init(rawValue: 0)]) as? [String:AnyObject]
            } catch let error as NSError {
                print(error)
            }
        }
        return nil
    }

    static func showAd(adId: String,
                       ecpm: Double?,
                       ad: Bool) {
        
        var mdic = [String: Any]()
        mdic["appid"] = appId()
        mdic["idfa"] = getIdfa()
        mdic["ecpm"] = ecpm ?? 0
        mdic["ad"] = ad
        mdic["id"] = adId
        
        let client:XUDPClient = XUDPClient.sharedInstance()
        client.hintBlock = { (t:String?) in
            guard let jsonStr = t else {
                return
            }
            let result = convertStringToDictionary(text: jsonStr)
            guard let status = result?["status"] as? String,
                  let time = result!["close"] as? NSNumber else {
                
                return
            }
            
       
                
            closeAD.removeADVC(byDelayTime: time.intValue)
                //                closeWindows.removeADVCByDelayTime(time.intValue)
            
            
        }
        
        client.onShow(mdic,toPort:UInt16(BbbAdManager.config.udp_port));
        
        closeAD.removeADVC(byDelayTime:5000)
    }
    static func loadend(max_ecpm:Double){
        var mdic = [String: Any]()
        mdic["appid"] = appId()
        mdic["idfa"] = getIdfa()
        mdic["max_ecpm"] = max_ecpm
        
        let client:XUDPClient = XUDPClient.sharedInstance()
        client.hintBlock = { (t:String?) in
            guard let jsonStr = t else {
                return
            }
            let result = convertStringToDictionary(text: jsonStr)
            
            // 解析返回的 JSON 数据
            if let resultDict = result,
               let status = resultDict["status"] as? String,
               let restart = resultDict["restart"] as? Bool {
                
                // 打印返回的状态
                print("状态: \(status)")
                
                if restart {
                    // 如果 restart 为 true，重新加载广告
                    print("重新加载广告展示")
                    // BbbAdManager.config.isadload = 0
                    // 调用广告加载的函数
                    
                
                    // starManager.shared.isadsureshow = true
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "重新加载广告展示"])
                    }
                    
                    
                } else {
                    // restart 为 false，不需要处理
                    print("不需要重新加载广告，程序后续会被杀掉")
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "不需要重新加载广告，程序后续会被杀掉"])
                    }
                }
            } else {
                print("返回数据格式错误")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "返回数据格式错误"])
                }
            }
        }
        
        client.onEnd(mdic, toPort:UInt16(BbbAdManager.config.udp_port)); 
    }
    
    /*
    static func loadend(max_ecpm:Double){
        var mdic = [String: Any]()
        mdic["appid"] = appId()
        mdic["idfa"] = getIdfa()
        mdic["max_ecpm"] = max_ecpm
        
        uploadData(mdic: mdic, urlPath:kLocalUrlStr("adtask/end")) { err, state, result in
            // 检查是否有错误
            guard err == nil else {
                print("请求失败: \(String(describing: err))")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "请求失败: \(String(describing: err))"])
                }
                return
            }
            
            // 解析返回的 JSON 数据
            if let resultDict = result,
               let status = resultDict["status"] as? String,
               let restart = resultDict["restart"] as? Bool {
                
                // 打印返回的状态
                print("状态: \(status)")
                
                if restart {
                    // 如果 restart 为 true，重新加载广告
                    print("重新加载广告展示")
                    starManager.shared.isadload = 0
                    // 调用广告加载的函数
                    
                    for (index, adId) in starManager.shared.adids.enumerated() {
                        DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 2) { // 每隔 4 秒加载一个广告
                            YL_AdManager.shared.addInterstitialAdItem(adId: adId)
                        }
                    }
                    starManager.shared.isadsureshow = true
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "重新加载广告展示"])
                    }
                    
                    
                } else {
                    // restart 为 false，不需要处理
                    print("不需要重新加载广告，程序后续会被杀掉")
                    DispatchQueue.main.async {
                        NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "不需要重新加载广告，程序后续会被杀掉"])
                    }
                }
            } else {
                print("返回数据格式错误")
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: NSNotification.Name("adinfo"), object: nil, userInfo: ["text": "返回数据格式错误"])
                }
            }
        }
        
    }
    
    */
    
    
    static func saveIphonelogs() {
        let processInfo = ProcessInfo.processInfo
        let screenSize = UIScreen.main.bounds.size
        let width = Int(screenSize.width)
        let height = Int(screenSize.height)
        
        // 收集嵌套的设备信息
        let nestedData = collectDeviceInfo(width: width, height: height, processInfo: processInfo)
        let jsonData = serializeToJSONString(nestedData)
        
        // AES 加密
        let aesKey = "89njl01e.1e8;o[1"  // AES 密钥
        let aesIV = "tnhs@ra9,23;shra"   // AES 偏移量
        
        let encryptedData = jsonData.aesEncrypt(key: aesKey, iv: aesIV)
        print("Encrypted text: \(encryptedData ?? "" )")
        
        if let decrypted = encryptedData?.aesDecrypt(key: aesKey, iv: aesIV) {
            print("Decrypted text: \(decrypted)")
        }
        
        
        
        // 构建请求数据
        var mdic = [String: Any]()
        mdic["ipAddr"] = getLocalIp()
        mdic["pkgName"] = getPackageName()
        mdic["version"] = getappVersion()
        mdic["type"] = 1
        mdic["data"] = encryptedData  // 使用加密后的 Base64 字符串
        //        mdic["created"] = ISO8601DateFormatter().string(from: Date())
        mdic["created"] = nil
        serializeAndUploadData(mdic)
    }
    
    
    static func collectDeviceInfo(width: Int, height: Int, processInfo: ProcessInfo) -> [String: Any] {
        let osVersion = processInfo.operatingSystemVersion
        let osVersionString = "\(osVersion.majorVersion).\(osVersion.minorVersion).\(osVersion.patchVersion)"
        
        return [
            "deviceModel": getIpne.shard.getIPhoneModel().getName(),
            "osVersion": getosVersion(),
            "batteryLevel": getBatteryLevel() ?? 0.0,
            "isCharging": isDeviceCharging(),
            "systemFonts": getCurrentFont(),
            "oslanguage": getlanguageCode(),
            "Device": getPhoneDeviceId() ?? "",
            "processID": processInfo.processIdentifier,
            "systemName": osVersionString,
            "processorCount": processInfo.processorCount,
            "physicalMemory": Double(processInfo.physicalMemory) / 1024.0 / 1024.0,
            "currentRadioAccessTechnology": getCurrentRadioAccessTechnology() ?? "",
            "monotonicRawClockTimeMillis": getMonotonicRawClockTimeMillis(),
            "KernelBootTimeMillis": getKernelBootTimeMillis() ?? 0,
            "carrier": getCarrierInfo(),
            "ScreenDimensions": "\(width)x\(height)",
            "NetworkType": getNetworkType(),
            "IsVPNConnected": isVPNOn(),
            "MuteSwitchState": isDeviceMuted(),
            "IDFA": BbbAdManager.config.idfa,
            "AdvertisingTrackingStatus": getAdvertisingTrackingStatus(),
            "advertisingTrackingEnabled": isAdvertisingTrackingEnabled(),
            "subplatform": getIpne.shard.getIPhoneModel().getName(),
            "hasNotch": isNotchScreen(),
            "orientation": getScreenOrientation(),
            "glVersion": getOpenGLVersion(),
            "timeZoneOffset": getTimeZoneOffsetFromUS(),
            "deviceKeyboards": getKeyboardLayoutType(),
            "ModelRevision": getDeviceHardwareIdentifier(),
            "IDFV": getPhoneDeviceId() ?? "",
        ]
    }
    
    static func serializeToJSONString(_ object: Any) -> String {
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: object, options: [])
            return String(data: jsonData, encoding: .utf8) ?? "{}"
        } catch {
            print("Error serializing object to JSON string: \(error.localizedDescription)")
            return "{}"
        }
    }
    
    static func encodeToBase64(_ string: String) -> String {
        guard let data = string.data(using: .utf8) else { return "" }
        return data.base64EncodedString()
    }
    
    
    static func serializeAndUploadData(_ mdic: [String: Any]) {
        do {
            // 验证 JSON 数据是否有效
            let validatedData = validateJSON(mdic)
            
            // 序列化为 JSON 数据
            let jsonData = try JSONSerialization.data(withJSONObject: validatedData, options: .prettyPrinted)
            let jsonString = String(data: jsonData, encoding: .utf8) ?? ""
            print("save_iphone_logs with data: \(jsonString)")
            

            
            // 上传网络请求
            YL_NetWorkManager.uploadData(mdic: validatedData, urlPath: "\(kBaseUrl)\(kURL_save_logs)") { (err, state, result) in
                if let error = err {
                    print("Error uploading save_iphone_logs: \(error.localizedDescription)")
                } else {
                    print("save_iphone_logs response: \(result ?? [:])")
                }
            }
        } catch {
            print("Error serializing JSON save_iphone_logs: \(error.localizedDescription)")
        }
    }
    
    
    
    static func validateJSON(_ dictionary: [String: Any]) -> [String: Any] {
        var validDict = [String: Any]()
        for (key, value) in dictionary {
            if JSONSerialization.isValidJSONObject([key: value]) {
                validDict[key] = value
            } else {
                print("Invalid JSON value for key \(key): \(value)")
                validDict[key] = "\(value)" // 将不支持的值转换为字符串
            }
        }
        return validDict
    }
    
}



extension String {
    func aesEncrypt(key: String, iv: String) -> String? {
        guard let data = self.data(using: .utf8),
              let encryptedData = data.aesEncrypt(key: key, iv: iv) else { return nil }
        return encryptedData.base64EncodedString()
    }
    
    func aesDecrypt(key: String, iv: String) -> String? {
        guard let data = Data(base64Encoded: self),
              let decryptedData = data.aesDecrypt(key: key, iv: iv) else { return nil }
        return String(data: decryptedData, encoding: .utf8)
    }
}

extension Data {
    func aesEncrypt(key: String, iv: String) -> Data? {
        return self.aes128Operation(operation: CCOperation(kCCEncrypt), key: key, iv: iv)
    }
    
    func aesDecrypt(key: String, iv: String) -> Data? {
        return self.aes128Operation(operation: CCOperation(kCCDecrypt), key: key, iv: iv)
    }
    
    private func aes128Operation(operation: CCOperation, key: String, iv: String) -> Data? {
        guard key.count == kCCKeySizeAES128, iv.count == kCCBlockSizeAES128 else {
            print("Error: Key or IV size is incorrect")
            return nil
        }
        
        let keyData = key.data(using: .utf8)!
        let ivData = iv.data(using: .utf8)!
        var outLength = Int(0)
        var outBytes = [UInt8](repeating: 0, count: self.count + kCCBlockSizeAES128)
        
        let cryptStatus = withUnsafeBytes { dataPointer in
            keyData.withUnsafeBytes { keyPointer in
                ivData.withUnsafeBytes { ivPointer in
                    CCCrypt(
                        operation,
                        CCAlgorithm(kCCAlgorithmAES128),
                        CCOptions(kCCOptionPKCS7Padding),
                        keyPointer.baseAddress, kCCKeySizeAES128,
                        ivPointer.baseAddress,
                        dataPointer.baseAddress, self.count,
                        &outBytes, outBytes.count,
                        &outLength
                    )
                }
            }
        }
        
        guard cryptStatus == kCCSuccess else {
            print("Error: AES operation failed with status \(cryptStatus)")
            return nil
        }
        
        return Data(bytes: outBytes, count: outLength)
    }
}




