//
//  MVLoginController.swift
//  MusicVideoPlus
//
//  Created by ak on 2021/6/2.
//

import AuthenticationServices
import BFFramework
import JWTDecode
import TYAttributedLabel
import UIKit

class MVLoginController: MVBaseController {
    let nomalH: CGFloat = cDefaultMargin * 5

    @available(iOS 13.0, *)
    lazy var appleSignBtn: ASAuthorizationAppleIDButton = {
        let appleSignBtn: ASAuthorizationAppleIDButton = ASAuthorizationAppleIDButton(type: .signIn, style: .black)
        appleSignBtn.cornerRadius = nomalH / 2
        appleSignBtn.isHidden = true
        appleSignBtn.frame = CGRect(x: 0, y: 0, width: nomalH, height: nomalH)
        appleSignBtn.center = view.center
        appleSignBtn.addTarget(self, action: #selector(appleLoginAction), for: .touchUpInside)
        return appleSignBtn
    }()

    lazy var protocolLab: TYAttributedLabel = {
        let protocolLab = TYAttributedLabel()
        protocolLab.highlightedLinkBackgroundColor = UIColor.white
        protocolLab.delegate = self
        protocolLab.numberOfLines = 0
        protocolLab.font = UIFont.systemFont(ofSize: 12)
        protocolLab.text = "登录即表明同意"
        protocolLab.textColor = UIColor.hexColor(hexadecimal: "#999999")
        protocolLab.appendLink(withText: "《软件许可及服务协议》", linkFont: UIFont.systemFont(ofSize: 12), linkColor: UIColor.hexColor(hexadecimal: "#08B706"), underLineStyle: CTUnderlineStyle.single, linkData: cUserProtocol)
        protocolLab.appendLink(withText: "和", linkFont: UIFont.systemFont(ofSize: 12), linkColor: UIColor.hexColor(hexadecimal: "#999999"), underLineStyle: CTUnderlineStyle(), linkData: nil)
        protocolLab.appendLink(withText: "《隐私政策》", linkFont: UIFont.systemFont(ofSize: 12), linkColor: UIColor.hexColor(hexadecimal: "#08B706"), underLineStyle: CTUnderlineStyle.single, linkData: cPrivacy)
        protocolLab.textAlignment = CTTextAlignment.center
        return protocolLab
    }()

    lazy var loginBtn: UIButton = {
        let loginBtn = UIButton(type: .custom)
        loginBtn.addTarget(self, action: #selector(wechatLoginAction), for: .touchUpInside)
        loginBtn.setTitleColor(UIColor.white, for: .normal)
        loginBtn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 0)
        loginBtn.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        loginBtn.setImage(UIImage(named: "weichatLogin"), for: .normal)
        loginBtn.addCorner(corner: nomalH / 2)
        return loginBtn
    }()

    lazy var phoneLoginBtn: UIButton = {
        let phoneLoginBtn = UIButton(type: .custom)
        phoneLoginBtn.addTarget(self, action: #selector(phoneLoginAction), for: .touchUpInside)
        phoneLoginBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#07C160"), for: .normal)
        phoneLoginBtn.setTitle(" 手机号登录", for: .normal)
        phoneLoginBtn.titleEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 0)

        phoneLoginBtn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
        phoneLoginBtn.setImage(UIImage(named: "icon_phone"), for: .normal)
        phoneLoginBtn.backgroundColor = UIColor.black
        phoneLoginBtn.addCorner(corner: nomalH / 2)
        return phoneLoginBtn
    }()

    // icon
    lazy var IconView: UIImageView = {
        let IconView = UIImageView(image: UIImage(named: "1024x1024px"))
        return IconView
    }()

    lazy var remindBtn: UIButton = {
        let remindBtn = UIButton(type: .custom)
        remindBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#333333")
        remindBtn.setTitleColor(UIColor.hexColor(hexadecimal: "#999999"), for: .normal)
        remindBtn.titleLabel?.font = UIFont.systemFont(ofSize: 13)
        remindBtn.setTitle(remindTitle, for: .normal)
        remindBtn.addCorner(corner: 12)
        return remindBtn
    }()

    var remindTitle: String? {
        didSet {
            remindBtn.setTitle("  \(remindTitle ?? "登录")  ", for: .normal)
        }
    }

    @objc override func backBtnClick() {
        dismiss(animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(IconView)
        view.addSubview(remindBtn)

        remindBtn.isHidden = !(remindTitle != nil && remindTitle?.count ?? 0 > 0)
        // 请求配置
        PQBaseViewModel.systemConfig { [weak self] _ in
            self?.view.addSubview(self!.loginBtn)
            self?.view.addSubview(self!.phoneLoginBtn)
            self?.view.addSubview(self!.protocolLab)
            if PQSingletoMemoryUtil.shared.needLogin {
                if #available(iOS 13.0, *) {
                    self?.view.addSubview(self!.appleSignBtn)
                    self?.appleSignBtn.isHidden = false
                    self?.loginBtn.setTitle(nil, for: .normal)
                    self?.phoneLoginBtn.setTitle(nil, for: .normal)
                }
                self?.loginBtn.setImage(UIImage(named: "mi_upload_share_friend"), for: .normal)
                self?.loginBtn.backgroundColor = UIColor.black
            } else {
                self?.loginBtn.setImage(UIImage(named: "weichatLogin"), for: .normal)
                self?.loginBtn.backgroundColor = UIColor.white
            }
            self?.addLayout()
            self?.phoneLoginBtn.isHidden = !PQSingletoMemoryUtil.shared.needLogin
        }

        IconView.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.height.width.equalTo(260)
        }
        addNotification(self, selector: #selector(dismissVC), name: cLoginSuccesssNotiKey, object: nil)
    }

    override func viewWillAppear(_: Bool) {
        super.viewWillAppear(true)

        showNavigation()
        leftButton(image: "close")
    }

    override public func viewWillDisappear(_: Bool) {
        super.viewWillDisappear(true)
    }

    func addLayout() {
        protocolLab.snp.makeConstraints { make in
            make.bottom.equalTo(view).offset(-cDefaultMargin * 5)
            make.left.equalTo(view).offset(cDefaultMargin * 2)
            make.right.equalTo(view).offset(-cDefaultMargin * 2)
            make.height.equalTo(cScreenHeigth <= 568 ? cDefaultMargin * 4 : cDefaultMargin * 6)
        }

        remindBtn.snp.makeConstraints { make in
//            make.width.equalTo(cDefaultMargin * 13)
            make.height.equalTo(cDefaultMargin * 4)
            make.centerX.equalTo(IconView)
            make.top.equalTo(IconView.snp_bottom).offset(cDefaultMargin * 4)
        }
        let isInstallWX = PQSingletoWXApiUtil.shared.isInstallWX()

        if PQSingletoMemoryUtil.shared.needLogin {
            if #available(iOS 13.0, *) {
                if isInstallWX {
                    loginBtn.snp.makeConstraints { make in
                        make.centerX.equalToSuperview()
                        make.height.width.equalTo(nomalH)
                        make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
                    }
                    phoneLoginBtn.snp.makeConstraints { make in
                        make.left.equalTo(loginBtn.snp_right).offset(cDefaultMargin * 4)
                        make.height.centerY.width.equalTo(loginBtn)
                    }
                    appleSignBtn.snp.makeConstraints { make in
                        make.right.equalTo(loginBtn.snp_left).offset(-cDefaultMargin * 4)
                        make.height.centerY.width.equalTo(loginBtn)
                    }
                } else {
                    appleSignBtn.snp.makeConstraints { make in
                        make.centerX.equalToSuperview().offset(-35)
                        make.height.width.equalTo(nomalH)
                        make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
                    }
                    phoneLoginBtn.snp.makeConstraints { make in
                        make.left.equalTo(appleSignBtn.snp_right).offset(cDefaultMargin * 4)
                        make.height.centerY.width.equalTo(appleSignBtn)
                    }
                }
            } else {
                if isInstallWX {
                    loginBtn.snp.makeConstraints { make in
                        make.left.right.equalTo(protocolLab)
                        make.height.equalTo(nomalH)
                        make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
                    }
                    phoneLoginBtn.snp.makeConstraints { make in
                        make.left.right.equalTo(protocolLab)
                        make.height.equalTo(nomalH)
                        make.bottom.equalTo(loginBtn.snp_top).offset(-cDefaultMargin)
                    }
                } else {
                    phoneLoginBtn.snp.makeConstraints { make in
                        make.left.right.equalTo(protocolLab)
                        make.height.equalTo(nomalH)
                        make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
                    }
                }
            }

        } else {
            loginBtn.snp.makeConstraints { make in
                make.left.right.equalTo(protocolLab)
                make.height.equalTo(nomalH)
                make.bottom.equalTo(protocolLab.snp_top).offset(-cDefaultMargin * 3)
            }
        }
    }

    deinit {
        PQNotification.removeObserver(self)
    }

    @objc func dismissVC() {
        dismiss(animated: true, completion: nil)
    }
}

extension MVLoginController: TYAttributedLabelDelegate {
    func attributedLabel(_: TYAttributedLabel!, textStorageClicked textStorage: TYTextStorageProtocol!, at _: CGPoint) {
        var link: String? = (textStorage as? TYLinkTextStorage)?.linkData as? String ?? ""
        if link == nil || (link?.count ?? 0) <= 0 {
            let range = (textStorage as? TYLinkTextStorage)?.range
            if range?.length == 11 {
                link = cUserProtocol
            } else if range?.length == 6 {
                link = cPrivacy
            }
        }
        let detail = PQBaseWebViewController()
        detail.modalPresentationStyle = .fullScreen
        detail.baseUrl = link
        present(detail, animated: true, completion: nil)
    }
}

extension MVLoginController: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
    @objc func wechatLoginAction() {
        if !PQSingletoWXApiUtil.shared.isInstallWX() {
            cShowHUB(superView: nil, msg: "您还未安装微信客户端！")
            return
        }
        PQSingletoWXApiUtil.shared.authorize().wxApiUtilHander = { [weak self] userData, errorMsg in
            if userData == nil {
                // cShowHUB(superView:nil, msg: errorMsg)
                return
            }
            PQMineViewModel.wechatLogin(unionid: "\(userData?["unionid"] ?? "")", openId: "\(userData?["openid"] ?? "")", nickName: "\(userData?["nickname"] ?? "")", avatarUrl: "\(userData?["headimgurl"] ?? "")") { [weak self] _, errorMsg in
                if errorMsg != nil {
                    cShowHUB(superView: nil, msg: "登录失败，请重试~")
                } else {
                    cShowHUB(superView: nil, msg: "登录成功")
                    self?.dismiss(animated: true, completion: {
                        postNotification(name: cLoginSuccesssNotiKey)
                    })
                }
            }
        }
    }

    @objc func phoneLoginAction() {
        let vc = PQPhoneLoginController()
        vc.modalPresentationStyle = .fullScreen
        present(vc, animated: true, completion: nil)
    }

    @objc func appleLoginAction() {
        if #available(iOS 13.0, *) {
            let appleIDProvider = ASAuthorizationAppleIDProvider()
            let appleRequest = appleIDProvider.createRequest()
            appleRequest.requestedScopes = [.fullName, .email]
            let auth = ASAuthorizationController(authorizationRequests: [appleRequest])
            auth.delegate = self
            auth.presentationContextProvider = self
            auth.performRequests()
        }
    }

    // Apple登录回调

    @available(iOS 13.0, *)
    func presentationAnchor(for _: ASAuthorizationController) -> ASPresentationAnchor {
        return view.window!
    }

    @available(iOS 13.0, *)
    func authorizationController(controller _: ASAuthorizationController, didCompleteWithError error: Error) {
        BFLog(message: "didCompleteWithError - \(error)")
        switch (error as NSError).code {
        case ASAuthorizationError.canceled.rawValue:
            cShowHUB(superView: nil, msg: "你取消了授权登录")
        case ASAuthorizationError.failed.rawValue:
            cShowHUB(superView: nil, msg: "授权失败，请重新登录")
        case ASAuthorizationError.invalidResponse.rawValue:
            cShowHUB(superView: nil, msg: "暂时无响应哦，请重新登录")
        case ASAuthorizationError.notHandled.rawValue:
            cShowHUB(superView: nil, msg: "暂时无响应哦，请重新登录")
        case ASAuthorizationError.unknown.rawValue:
            cShowHUB(superView: nil, msg: "暂时无响应哦，请重新登录")
        default:
            break
        }
    }

    @available(iOS 13.0, *)
    func authorizationController(controller _: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if authorization.credential.isKind(of: ASAuthorizationAppleIDCredential.self) {
            let credential: ASAuthorizationAppleIDCredential = authorization.credential as! ASAuthorizationAppleIDCredential
            let user = credential.user
            let identityToken = credential.identityToken
            let token = String(data: identityToken!, encoding: .utf8)
            if valideToken(token: token, user: user) {
                PQMineViewModel.appleLogin(token: token ?? "") { [weak self] _, errorMsg in
                    if errorMsg != nil {
                        cShowHUB(superView: nil, msg: errorMsg)
                    } else {
                        cShowHUB(superView: nil, msg: "登录成功")

                        self?.dismiss(animated: true, completion: nil)
                        postNotification(name: cLoginSuccesssNotiKey)
                    }
                }
            } else {
                cShowHUB(superView: nil, msg: "校验失败,请重新登录")
            }
        } else if authorization.credential.isKind(of: ASPasswordCredential.self) {
            let credential: ASPasswordCredential = authorization.credential as! ASPasswordCredential
            let user = credential.user
            BFLog(message: "user = \(user)")
        }
    }

    /// 本地校验
    /// - Parameters:
    ///   - identityToken: <#identityToken description#>
    ///   - user: <#user description#>
    /// - Returns: <#description#>
    func valideToken(token: String?, user: String) -> Bool {
        if token == nil || (token?.isEmpty ?? true) {
            return false
        }
        let jwt = try! decode(jwt: token!)
        BFLog(message: "\(jwt)")
        if jwt.body.keys.contains("sub") {
            let sub: String = jwt.body["sub"] as! String
            if sub == user { // 校验成功
                return true
            }
        }
        return false
    }
}
