//
//  PQThirdPlatformUtil.swift
//  PQSpeed
//
//  Created by SanW on 2020/5/30.
//  Copyright © 2020 BytesFlow. All rights reserved.
//

import Kingfisher
import UIKit
import UserNotifications
import WechatOpenSDK
import BFCommonKit

// MARK: - Bugly初始化工具类

public class PQSingletoBuglyUtil: NSObject {
    public static let shared = PQSingletoBuglyUtil()

    public func registerBugly(appID: String) {
        let versionName = "\(Bundle.main.infoDictionary?["CFBundleShortVersionString"] ?? "1.0.0")"

        // 注册bugly
        let buglyConfig = BuglyConfig()
        buglyConfig.reportLogLevel = .warn
        #if DEBUG
            buglyConfig.version = versionName + ".6666"
            buglyConfig.debugMode = true
        #else
            if PQENVUtil.shared.envMode == .ENVModeOnline {
                buglyConfig.version = versionName + "." + versionCode
            } else if PQENVUtil.shared.envMode == .ENVModePre {
                buglyConfig.version = versionName + ".8888"
            } else {
                buglyConfig.version = versionName + ".9999"
            }
        #endif
        BFLog(message: "Bugly版本号：\(BuglyConfig.version())")
        buglyConfig.channel = channelID
        buglyConfig.deviceIdentifier = BFLoginUserInfo.shared.isLogin() ? BFLoginUserInfo.shared.uid : getMachineCode()
        buglyConfig.unexpectedTerminatingDetectionEnable = true
        buglyConfig.blockMonitorEnable = true
        buglyConfig.blockMonitorTimeout = 2
        Bugly.start(withAppId: appID, config: buglyConfig)
    }
}

// MARK: - 微信相关工具类

// 初始化微信要使用的参数 e.g.
/*
     let state: String = "com.piaoquan.pqspeed"
     let appid: String = "wxfc2fc07ab379e4bf"
     let secret: String = "06f696424accb17b7234dce32e4821b4"
     let universalLink: String = "https://speed.piaoquantv.com/"
     let scope = "snsapi_userinfo"
 */
public class WXApiInfo: NSObject {
    public var state: String = ""
    public var appid: String = ""
    public var secret: String = ""
    public var universalLink: String = ""
    public var scope = ""
}

public class PQSingletoWXApiUtil: NSObject {
    public static let shared = PQSingletoWXApiUtil()
    var openId: String? // openID
    // 回调
    public var wxApiUtilHander: ((_ userData: [String: Any]?, _ errorMsg: String?) -> Void)?
    var mAppInfo: WXApiInfo = WXApiInfo()
    public func registerApp(appInfo: WXApiInfo?) {
        if appInfo == nil {
            return
        }
        mAppInfo = appInfo!
        #if DEBUG
            WXApi.startLog(by: .detail) { msg in
                BFLog(message: "微信回调Log--\(msg)")
            }
        #endif
        WXApi.registerApp(mAppInfo.appid, universalLink: mAppInfo.universalLink)
//        #if DEBUG
//            WXApi.checkUniversalLinkReady { step, result in
//                BFLog(message: "微信回调自检--\(step)，result = \(result)")
//            }
//        #endif
    }

    public func handleOpen(url: URL) -> Bool {
        return WXApi.handleOpen(url, delegate: self)
    }

    public func handleOpenUniversalLink(userActivity: NSUserActivity) -> Bool {
        return WXApi.handleOpenUniversalLink(userActivity, delegate: self)
    }

    public func authorize() -> PQSingletoWXApiUtil {
        if !isInstallWX() {
            if wxApiUtilHander != nil {
                wxApiUtilHander!(nil, "您还未安装微信客户端！")
            }
            return .shared
        }
        let req = SendAuthReq()
        req.scope = mAppInfo.scope
        req.state = mAppInfo.state
        WXApi.send(req) { [weak self] isSuccess in
            if !isSuccess {
                self?.wxApiUtilHander!(nil, "您还未安装微信客户端！")
            }
        }
        return .shared
    }

    /// 分享
    /// - Parameters:
    ///   - type: 类型 1- 分享视频 2-分享活动 3-分享卡点视频
    ///   - scene: 场景
    ///   - title: 标题
    ///   - description:描述
    ///   - imageUrl: 图片url
    ///   - path: 网页地址
    ///   - videoId: 视频ID type == 1时不为空
    ///   - pageSource: 页面pageSource type == 1时不为空
    /// - Returns: <#description#>
    public func share(type: Int = 1, scene: Int32, shareWeappRawId: String? = nil, title: String?, description: String?, imageUrl: String?, path: String?, videoId: String, pageSource: PAGESOURCE, shareId: String) -> PQSingletoWXApiUtil {
        if !isInstallWX() {
            if wxApiUtilHander != nil {
                wxApiUtilHander!(nil, "您还未安装微信客户端！")
            }
            return .shared
        }
        let message = WXMediaMessage()
        message.title = title ?? ""
        message.description = description ?? ""

        ImageDownloader.default.downloadImage(with: URL(string: imageUrl ?? "")!, options: nil) { result in
            switch result {
            case let .success(imageResult):
                message.thumbData = zipImage(image: imageResult.image, size: 64)
                if type == 1 || type == 3, scene == Int32(WXSceneSession.rawValue) {
                    let wxMiniObject = WXMiniProgramObject()
                    wxMiniObject.miniProgramType = PQENVUtil.shared.envMode == .ENVModeOnline ? .release : .test
                    wxMiniObject.userName = shareWeappRawId ?? cShareWeappRawId
                    var homePagePath: String = ""
                    var targetPagePath: String = ""
                    var isRhythmVideo = 0
                    if type == 3 {
                        homePagePath = "pages/post/post"
                        targetPagePath = "package-point/show/show"
                        isRhythmVideo = 1
                    } else {
                        homePagePath = "pages/category"
                        targetPagePath = "user-videos"
                        isRhythmVideo = 0
                    }
                    var params = (targetPagePath + "?id=\(videoId)&tp=share&rootPageSource=\(pageSource.rawValue)&shareDepth=1&rootLaunchShareId=\(shareId)&parentShareId=\(shareId)&shareId=\(shareId)&shareAppType=\(PQBFConfig.shared.appType)&mid=\(getMachineCode())&su=\(BFLoginUserInfo.shared.uid)&isRhythmVideo=\(isRhythmVideo)").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
                    ["/", "=", "?", "&"].forEach { char in
                        let custom = CharacterSet(charactersIn: char).inverted
                        params = params?.addingPercentEncoding(withAllowedCharacters: custom) ?? ""
                    }
                    wxMiniObject.path = "\(homePagePath)?jumpPage=" + (params ?? "")
                    wxMiniObject.webpageUrl = "https://piaoquan.yishihui.com/"
                    wxMiniObject.hdImageData = message.thumbData
                    message.mediaObject = wxMiniObject

                } else {
                    let webpageObject = WXWebpageObject()
                    webpageObject.webpageUrl = path ?? ""
                    message.mediaObject = webpageObject
                }

                let req = SendMessageToWXReq()
                req.message = message
                req.scene = scene
                WXApi.send(req) { [weak self] isSuccess in
                    if self?.wxApiUtilHander != nil {
                        self?.wxApiUtilHander!(nil, isSuccess ? "分享成功～" : "分享失败了～")
                    }
                }
            case let .failure(error):
                BFLog(message: "下载图片失败：\(error.localizedDescription)")
            }
        }
        return .shared
    }

    /// 处理发起数据
    /// - Parameter response: <#response description#>
    /// - Returns: <#description#>
    public func dealWithPayParams(response: [String: Any]) -> PQSingletoWXApiUtil {
        var partnerid: String = ""
        var prepayId: String = ""
        var nonceStr: String = ""
        var timeStamp: UInt32 = 0
        var package: String = "Sign=WXPay"
        var sign: String = ""
        if response.keys.contains("partnerid") {
            partnerid = response["partnerid"] as! String
        }
        if response.keys.contains("prepayid") {
            prepayId = response["prepayid"] as! String
        }
        if response.keys.contains("noncestr") {
            nonceStr = response["noncestr"] as! String
        }
        if response.keys.contains("timestamp") {
            timeStamp = UInt32(Int("\(response["timestamp"] ?? "0")") ?? 0)
        }
        if response.keys.contains("package") {
            package = response["package"] as! String
        }
        if response.keys.contains("sign") {
            sign = response["sign"] as! String
        }
        requestPayReq(partnerid: partnerid, prepayId: prepayId, nonceStr: nonceStr, timeStamp: timeStamp, package: package, sign: sign)
        return .shared
    }

    /// 发起
    /// - Parameters:
    ///   - partnerid: 商家向财付通申请的商家id
    ///   - prepayId: 预
    ///   - nonceStr: 随机串，防重发
    ///   - timeStamp: 时间戳，防重发
    ///   - package: 商家根据财付通文档填写的数据和签名
    ///   - sign: 商家根据微信开放平台文档对数据做的签名
    /// - Returns: <#description#>
    public func requestPayReq(partnerid: String, prepayId: String, nonceStr: String, timeStamp: UInt32, package: String, sign: String) {
        // 调起微信
        let payReq: PayReq = PayReq()
        payReq.partnerId = partnerid
        payReq.prepayId = prepayId
        payReq.nonceStr = nonceStr
        payReq.timeStamp = timeStamp
        payReq.package = package
        payReq.sign = sign
        WXApi.send(payReq) { _ in
        }
    }

    /// 是否安装了微信
    /// - Returns: <#description#>
    public func isInstallWX() -> Bool {
        return UIApplication.shared.canOpenURL(URL(string: "weixin://")!)
    }

    override private init() {
        super.init()
    }

    override public func copy() -> Any {
        return self
    }

    override public func mutableCopy() -> Any {
        return self
    }
}

extension PQSingletoWXApiUtil: WXApiDelegate {
    public func onReq(_ req: BaseReq) {
        BFLog(message: "微信回调拉起 -- \(req)")
        if req.isKind(of: LaunchFromWXReq.self) && ((req as! LaunchFromWXReq).message.messageExt?.count ?? 0) > 0 {
            BFLog(message: "小程序回调数据--\(String(describing: (req as! LaunchFromWXReq).message.messageExt))")
//            PQBoardCommandUtil.dealWithPasteboardData(messageExt: (req as! LaunchFromWXReq).message.messageExt)
        }
    }

    public func onResp(_ resp: BaseResp) {
        BFLog(message: "微信回调返回 -- \(resp)")

        if resp.isKind(of: SendAuthResp.self) {
            if (resp as! SendAuthResp).state == mAppInfo.state {
                accessToken(code: (resp as! SendAuthResp).code!)
            } else {
                if wxApiUtilHander != nil {
                    wxApiUtilHander!(nil, "网络不可用")
                }
            }
        } else if resp.isKind(of: PayResp.self) {
            if wxApiUtilHander != nil {
                wxApiUtilHander!(["returnKey": (resp as! PayResp).returnKey, "code": resp.errCode], resp.errStr)
            }
        }
    }

    public func accessToken(code: String) {
        let url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=\(mAppInfo.appid)&secret=\(mAppInfo.secret)&code=\(code)&grant_type=authorization_code"
        DispatchQueue.global(qos: .userInitiated).async { [weak self] in

            let zoneStr = try? String(contentsOf: URL(string: url)!, encoding: .utf8)
            if zoneStr == nil {
                if self?.wxApiUtilHander != nil {
                    self?.wxApiUtilHander!(nil, "授权失败了～")
                }
                return
            }
            let data = zoneStr!.data(using: .utf8)
            let dict: [String: Any] = try! JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: Any]
            self?.openId = "\(dict["openid"] ?? "")"
            BFLoginUserInfo.shared.openId = self?.openId ?? ""
            let access_token: String = "\(dict["access_token"] ?? "")"

            let userUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=\(access_token)&openid=\(self?.openId ?? "")"

            DispatchQueue.global(qos: .userInitiated).async {
                let userInfoStr = try? String(contentsOf: URL(string: userUrl)!, encoding: .utf8)
                let userInfoData = userInfoStr!.data(using: .utf8)
                let userDict: [String: Any] = try! JSONSerialization.jsonObject(with: userInfoData!, options: .mutableContainers) as! [String: Any]
                DispatchQueue.main.async { [weak self] in
                    if userDict.count > 0 {
                        if self?.wxApiUtilHander != nil {
                            self?.wxApiUtilHander!(userDict, nil)
                        }
                    } else {
                        if self?.wxApiUtilHander != nil {
                            self?.wxApiUtilHander!(nil, "授权失败了～")
                        }
                    }
                }
            }
        }
    }
}
