//
//  HomePayModel.swift
//  PhoneManager
//
//  Created by edy on 2025/4/7.
//

import UIKit
import StoreKit
import SVProgressHUD


class HomePayModel: NSObject ,SKProductsRequestDelegate ,SKPaymentTransactionObserver {
    
    static let share:HomePayModel = HomePayModel()
    
    private let userDefaults = UserDefaults.standard
    private let productCacheKey = "IAPProductCache"
    
    enum PayState {
    case Subscribe   // 订阅
    case NonConsum   // 非消耗型
    }
    
    var state:PayState = .Subscribe
    
    private let productIdentifiers:[String] = ["com.app.phonemanager.week.member.se" , "com.app.phonemanager.lifetime.member"]
    
    var isSubscribed:Bool = false
    var isNoAd:Bool {
        get {
            guard let noabd = UserDefaults.standard.object(forKey: "noabd") as? Bool else { return false }
            return noabd
        }
        set {
            UserDefaults.standard.setValue((newValue), forKey: "noabd")
            NotificationCenter.default.post(name: .HelperPurchaseNotification, object: nil)
            UserDefaults.standard.synchronize()
        }
    }
    
    var storeCall:((_ product:[SKProduct?]) -> Void) = { prod in }
    
    public func loadLocalData() -> Void {
        verifyReceiptWithApple { receipt in
            guard let json = receipt else {
                self.refreshReceipt()
                return
            }
            let sub = self.checkSubscriptionStatus(receiptInfo: json)
            if sub.0 == true {
                let extDate = sub.2
                self.isNoAd = true
#if DEBUG
                let s = DateFormatter()
                s.dateFormat = "yyyyMMdd HHmmss"
                Print("ext : %@", s.string(from: extDate ?? Date()))
#endif
            }
        }
    }
    
    private func checkTrialStatus() -> Void {
        if state == .Subscribe { // 订阅型
            verifyReceiptWithApple { receipt in
                self.alert.disMiss()
                guard let json = receipt else {
                    self.refreshReceipt()
                    return
                }
                let sub = self.checkSubscriptionStatus(receiptInfo: json)
                if sub.0 == true {
                    let extDate = sub.2
                    self.isNoAd = true
#if DEBUG
                    let s = DateFormatter()
                    s.dateFormat = "yyyyMMdd HHmmss"
                    Print("ext : %@", s.string(from: extDate ?? Date()))
#endif
                }else{
                    self.isNoAd = false
                }
                DismissPresen()
            }
        }else{
            self.alert.disMiss()
            self.isNoAd = true
            DismissPresen()
        }
    }
    
    func cacheProducts(_ products: [SKProduct]) {
        var productCache = [[String: Any]]()
        for product in products {
            let productInfo: [String: Any] = [
                "productIdentifier": product.productIdentifier,
                "localizedTitle": product.localizedTitle,
                "localizedDescription": product.localizedDescription,
                "price": product.price.doubleValue,
                "priceLocale": product.priceLocale.identifier
            ]
            productCache.append(productInfo)
        }
        userDefaults.set(productCache, forKey: productCacheKey)
    }
    
    func getCachedProduct(forIdentifier identifier: [String]) -> [SKProduct]? {
        var products: [SKProduct] = []
        // 从 UserDefaults 中获取缓存数据
        if let productCache = userDefaults.object(forKey: productCacheKey) as? [[String: Any]] {
            for item in productCache {
                // 从字典中提取价格和价格区域设置信息
                let price = NSDecimalNumber(value: item["price"] as? Double ?? 0)
                let priceLocaleIdentifier = item["priceLocale"] as? String ?? ""
                let priceLocale = Locale(identifier: priceLocaleIdentifier)
                // 创建 SKProduct 实例
                let mockProduct = SKProduct()
                // 设置商品标识符
                if let firstIdentifier = identifier.first {
                    mockProduct.setValue(firstIdentifier, forKey: "productIdentifier")
                }
                // 设置商品本地化标题
                mockProduct.setValue(item["localizedTitle"] as? String, forKey: "localizedTitle")
                // 设置商品本地化描述
                mockProduct.setValue(item["localizedDescription"] as? String, forKey: "localizedDescription")
                // 设置商品价格
                mockProduct.setValue(price, forKey: "price")
                // 设置商品价格的区域设置
                mockProduct.setValue(priceLocale, forKey: "priceLocale")
                // 将商品添加到结果数组中
                products.append(mockProduct)
            }
        }
        return products
    }
    
    func fetchProducts()  {
        Print("获取商品信息")
        // 看缓存里面有没有 有的话直接返回
        if let cachedProduct = self.getCachedProduct(forIdentifier: productIdentifiers) {
            var ps:[SKProduct?] = [nil,nil]
            if cachedProduct.count >= 2 {
                if cachedProduct.first?.productIdentifier == productIdentifiers.first {
                    ps[0] = cachedProduct.first
                    ps[1] = cachedProduct.last
                }else{
                    ps[1] = cachedProduct.first
                    ps[0] = cachedProduct.last
                }
            }else{
                ps = cachedProduct
            }
            self.product = ps
            self.storeCall(ps)
            Print("获取商品信息成功--读取缓存数据")
        }
        
        // 后续重新获取价格缓存
        BackgroundTaskManager.share.startTask()
        let request = SKProductsRequest(productIdentifiers: Set(productIdentifiers))
        request.delegate = self
        request.start()
        
        DispatchQueue.global().asyncAfter(deadline: .now() + 15) {
            request.cancel()
            BackgroundTaskManager.share.endTask()
        }
    }
    
    private var product:[SKProduct?]?
    
    /** 获取商品列表 */
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        let products = response.products
        var ps:[SKProduct] = []
        
        if products.count >= 2 {
            
            if let first = products.first,let last = products.last{
                
                if first.productIdentifier == productIdentifiers.first{
                    ps = [first,last]
                }else{
                    ps = [last,first]
                }
            }
            Print("获取商品信息成功")
            self.product = ps
            DispatchQueue.main.async{
                self.storeCall(ps)
                self.cacheProducts(ps)
                BackgroundTaskManager.share.endTask()
            }
        }else{
            self.product = products
        }
        
//        if products.count >= 2 {
//            if products.first?.productIdentifier == productIdentifiers.first {
//
//                ps = [products.first,products.last]
//            }else{
//                ps = [products.last,products.first]
//            }
//        }else{
//            ps = products
//        }
        
        
        
//        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: {
//            Print("获取商品信息成功")
//            if self.getCachedProduct(forIdentifier: self.productIdentifiers)?.count == 0 {
//                Print("获取商品信息成功--缓存没有数据由请求提供")
//                self.product = ps
//                self.storeCall(ps)
//            }
//            Print("开始缓存商品信息")
//            self.cacheProducts(products)
//            Print("缓存商品信息成功")
//            BackgroundTaskManager.share.endTask()
//           
//        })
    }

    func request(_ request: SKRequest, didFailWithError error: Error) {
        BackgroundTaskManager.share.endTask()
    }
    
    /** 购买 */
    func purchase(_ states:PayState = .Subscribe) -> Void {
        guard let p1 = product?.first,
              let p2 = product?.last,
              SKPaymentQueue.canMakePayments()
        else { return }
        self.state = states
        let payment = SKPayment(product: states == .Subscribe ? p1! : p2!)
        SKPaymentQueue.default().add(payment)
        alert.show("Loading... Please wait.","")
    }
    
    /** 恢复 */
    func restore(_ states:PayState = .Subscribe) -> Void {
        self.state = states
        SKPaymentQueue.default().restoreCompletedTransactions()
        alert.show("Loading... Please wait.","")
    }

    override init() {
        super.init()
        SKPaymentQueue.default().add(self)
    }
    
    let alert = PMLoadingHUD.share
    
}

extension HomePayModel {
    
    /** 购买回调 */
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) -> Void {
        guard let transaction = transactions.first else { return }
        switch transaction.transactionState {
        case .purchasing:
            Print("购买中...")
            break
        case .purchased:
            Print("购买成功")
            self.handlePurchased(transaction)
            break
        case .failed:
            Print("购买失败")
            alert.disMiss()
            SKPaymentQueue.default().finishTransaction(transaction)
            break
        case .restored:
            Print("恢复购买")
            self.restore()
            break
        default: break
            
        }
    }
    
    /** 购买成功 */
    private func handlePurchased(_ transaction: SKPaymentTransaction) {
        checkTrialStatus()
        SKPaymentQueue.default().finishTransaction(transaction)
    }

    
    func verifyReceiptWithApple(completion: @escaping (_ receipt:[String:Any]?) -> Void ) {
        guard let receiptURL = Bundle.main.appStoreReceiptURL,
              let receiptData = try? Data(contentsOf: receiptURL) else {
            completion(nil)
            return
        }
        let requestData: [String: Any] = [
            "receipt-data": receiptData.base64EncodedString(),
            "password": "3cbeb6f5ace84f5b98571263da74c192",
            "exclude-old-transactions": true
        ]
        // 2. 创建请求
        let url = URL(string: "https://buy.itunes.apple.com/verifyReceipt")! // 生产环境
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = try? JSONSerialization.data(withJSONObject: requestData)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if error != nil {
                completion(nil)
                return
            }
            guard let data = data else {
                completion(nil)
                return
            }
            do {
                if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                    if let status = json["status"] as? Int, status == 21007 {
                        self.verifySandboxReceipt(receiptData: receiptData) { receipt in
                            completion(receipt)
                        }
                    } else {
                        completion(json)
                    }
                } else {
                    completion(nil)
                }
            } catch {
                completion(nil)
            }
        }
        task.resume()
    }

    /** 验证收据 */
    private func verifySandboxReceipt(receiptData: Data, completion: @escaping (_ receipt:[String:Any]?) -> Void) {
        let base64Receipt = receiptData.base64EncodedString()
        let requestData: [String: Any] = [
            "receipt-data": base64Receipt,
            "password": "3cbeb6f5ace84f5b98571263da74c192",
            "exclude-old-transactions": true
        ]
        let url = URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")! // 沙盒环境
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = try? JSONSerialization.data(withJSONObject: requestData)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                completion(nil)
                return
            }
            guard let data = data else {
                completion(nil)
                return
            }
            do {
                if let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] {
                    completion(json)
                } else {
                    completion(nil)
                }
            } catch {
                completion(nil)
            }
        }
        
        task.resume()
    }
    
    /** 获取订阅状态 */
    func checkSubscriptionStatus(receiptInfo: [String: Any]) -> (isActive: Bool, isTrial: Bool, expiresDate: Date?) {
        guard let latestReceiptInfo = receiptInfo["latest_receipt_info"] as? [[String: Any]] else {
            return (false, false, nil)
        }
        // 获取最新的订阅信息
        guard let lastReceipt = latestReceiptInfo.first else {
            return (false, false, nil)
        }
        // 解析试用期状态
        let isTrial = (lastReceipt["is_trial_period"] as? String) == "true"
        // 解析到期时间
        var expiresDate: Date?
        if let expiresDateMs = lastReceipt["expires_date_ms"] as? String,
           let timeInterval = TimeInterval(expiresDateMs) {
            expiresDate = Date(timeIntervalSince1970: timeInterval / 1000.0)
        } else if let expiresDateString = lastReceipt["expires_date"] as? String {
            let formatter = ISO8601DateFormatter()
            expiresDate = formatter.date(from: expiresDateString)
        }
        // 检查订阅是否有效
        let isActive: Bool
        if let date = expiresDate {
            isActive = date > Date()
        } else {
            isActive = false
        }
        return (isActive, isTrial, expiresDate)
    }

    /** 恢复购买 */
    func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) -> Void {
        checkTrialStatus()
    }
    
    /** 恢复失败 */
    func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: any Error) {
        alert.disMiss()
    }
    
    /** 刷新收据 */
    func refreshReceipt() {
        let request = SKReceiptRefreshRequest()
        request.delegate = self
        request.start()
    }
}

extension HomePayModel {
    /// 检查订阅状态
    /// - Parameter completion: 回调闭包，返回订阅状态和到期时间
    func checkSubscriptionState(completion: @escaping (_ isSubscribed: Bool, _ expiresDate: Date?) -> Void) {
        verifyReceiptWithApple { receipt in
            guard let json = receipt else {
                self.refreshReceipt()
                completion(false, nil)
                return
            }
            
            let status = self.checkSubscriptionStatus(receiptInfo: json)
            DispatchQueue.main.async {
                completion(status.isActive, status.expiresDate)
                // 更新本地订阅状态
                self.isNoAd = status.isActive
                self.isSubscribed = status.isActive
                #if DEBUG
                if let expDate = status.expiresDate {
                    let formatter = DateFormatter()
                    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
                    Print("订阅状态：\(status.isActive ? "已订阅" : "未订阅")，到期时间：\(formatter.string(from: expDate))")
                }
                #endif
            }
        }
    }
}


extension Notification.Name {
    static let HelperPurchaseNotification = Notification.Name("PhoneManagerisStore")
}


