//
//  AppUpdateTool.swift
//  OrderScheduling
//
//  Created by 中道 on 2023/8/21.
//

import Foundation
import StoreKit
import RxSwift
import RxRelay
import RxCocoa
import DDUtilsSwiftKit_Private

public let APPUPDATE = AppUpdateTool.default

open class AppUpdateTool : NSObject {
    public static let `default` = AppUpdateTool()
    public let requestAppUpdateRelay = ReplayRelay<FromTypeEnum>.create(bufferSize: 1)
    private let disposeBag = DisposeBag()
    public let appUpdateView = AppUpdateView()
    
    public enum FromTypeEnum : Int {
        case auto = 1
        case manual
    }
    
    private var ignoreFlag : Bool? {
        return UserDefaults.standard.object(forKey: appUpdateIgnore_key) as? Bool
    }
    
    func setIgnoreFlag(ignoreFlag:Bool) {
        UserDefaults.standard.setValue(ignoreFlag, forKey: appUpdateIgnore_key)
    }
    
    public override init() {
        super.init()
        
        appUpdateView.updateButton.rx.tap
        .observe(on: MainScheduler.instance)
        .subscribe(onNext: {[weak self] _ in
            self?.openAppStore(by: UIApplication.shared.dd_keyWindow.rootViewController)
        })
        .disposed(by: disposeBag)
        
        appUpdateView.ignoreButton.rx.tap
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] _ in
                ENTRY.dismiss(name: appUpdateEntry) {[weak self] in
                    self?.setIgnoreFlag(ignoreFlag: true)
                }
            })
            .disposed(by: disposeBag)
        
        Observable.combineLatest(requestAppUpdateRelay, USER.refreshTokenSub)
            .filter({ (_,_) in
                return USER.isLogin == true
            })
            .observe(on: MainScheduler.instance)
            .do(onNext: { (_,_) in
                UIApplication.shared.dd_keyWindow.rootViewController?.view.dd_showHUD()
            })
            .flatMapLatest { (type,_) in
                return Observable.zip(RQ.updateVersion(parameters: UpdateVersionParameters(appVersion: APPINFO.bundleVersionShort(), supplierId: UserData.default.supplierId)).asObservable(), Observable.just(type))
            }
            .observe(on: MainScheduler.instance)
            .do(onNext: { (_,_) in
                UIApplication.shared.dd_keyWindow.rootViewController?.view.dd_hideHUD()
            })
            .observe(on: MainScheduler.instance)
            .subscribe(onNext: {[weak self] (response,type) in
                if response?.success == true {
                    
                    if response?.data == nil {
                        return
                    }
                    
                    if self?.canUpdate(localVersion: APPINFO.bundleVersionShort(), onlineVersion: response?.data?.newAppVersion ?? "0") == true {
                        if type == .auto {
                            if response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue || self?.shouldPresentEntry() == true {
                                if let appUpdateView = self?.appUpdateView {
                                    appUpdateView.isForce(isForce: (response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue) ? true : false)
                                    appUpdateView.contentLabel.text = response?.data?.description
                                    ENTRY.showAppUpdateEntry(view: appUpdateView,name: appUpdateEntry)
                                }
                            }
                        }else if type == .manual {
                            if let appUpdateView = self?.appUpdateView {
                                appUpdateView.isForce(isForce: (response?.data?.update == UpdateVersionDataModel.ForceUpdate.force.rawValue) ? true : false)
                                appUpdateView.contentLabel.text = response?.data?.description
                                ENTRY.showAppUpdateEntry(view: appUpdateView,name: appUpdateEntry)
                            }
                        }
                    }else{
                        if type == .manual {
                            UIApplication.shared.dd_keyWindow.rootViewController?.view.dd_makeToast(isTheNewestVserion)
                        }
                    }
                }else{
                    UIApplication.shared.dd_keyWindow.rootViewController?.view.dd_makeToast(response?.msg)
                }
            })
            .disposed(by: disposeBag)
    }
    
    func canUpdate(localVersion:String,onlineVersion:String) -> Bool {
        let onlineIntVersion = Int(onlineVersion.replacingOccurrences(of: ".", with: "")) ?? 0
        let localIntVersion = Int(localVersion.replacingOccurrences(of: ".", with: "")) ?? 0
        if onlineIntVersion > localIntVersion {
            return true
        }
        
        // 当app更新到最新版本时需要重置忽略
        setIgnoreFlag(ignoreFlag: false)
        
        return false
    }
    
    func shouldPresentEntry() -> Bool {
        if ignoreFlag == true {
            return false
        }
        return true
    }
    
    func openAppStore(by from:UIViewController?) {
        let vc = SKStoreProductViewController()
        vc.delegate = self
        vc.loadProduct(withParameters: [SKStoreProductParameterITunesItemIdentifier:AppItunesId])
        from?.present(vc, animated: true)
    }
}

extension AppUpdateTool : SKStoreProductViewControllerDelegate {
    public func productViewControllerDidFinish(_ viewController: SKStoreProductViewController) {
        viewController.dismiss(animated: true)
    }
}
