//
//  SignInAppleLogin.swift
//  E-Wow
//
//  Created by dong on 2021/1/6.
//

import AuthenticationServices
import UIKit

protocol SignInAppleLoginDelegate: NSObjectProtocol {
    func signInAppleAuth(token: String, userId: String, name: String)
}


@available(iOS 13.0, *)
class SignInAppleLogin: NSObject {
    var appleIDProvider: ASAuthorizationAppleIDProvider!
    weak var delegate: SignInAppleLoginDelegate?
    
    override init() {
        super.init()

        appleIDProvider = ASAuthorizationAppleIDProvider()
        NotificationCenter.default.addObserver(self, selector: #selector(notiSignWithAppleIDStateChanged(noti:)), name: NSNotification.Name(ASAuthorizationAppleIDProvider.credentialRevokedNotification.rawValue), object: nil)
    }

    func loginByApple() {
        let request = appleIDProvider.createRequest()
        request.requestedScopes = [.fullName, .email]
        // fix cancel animation: https://developer.apple.com/forums/thread/683981
        // let vc = ASAuthorizationController(authorizationRequests: [request, ASAuthorizationPasswordProvider().createRequest()])
        let vc = ASAuthorizationController(authorizationRequests: [request])
        vc.presentationContextProvider = self
        vc.delegate = self
        vc.performRequests()
    }

    // MARK: noti

    @objc func notiSignWithAppleIDStateChanged(noti: Notification) {
        dlog("apple id state chagned: \(noti.name)  \(noti.userInfo?.description ?? "")")
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

@available(iOS 13.0, *)
extension SignInAppleLogin: ASAuthorizationControllerDelegate {
    // 🔥🔥🔥
    func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
        if authorization.credential.isKind(of: ASAuthorizationAppleIDCredential.classForCoder()) {
            // 用户登录使用ASAuthorizationAppleIDCredential
            let appleIDCredential = authorization.credential as! ASAuthorizationAppleIDCredential
            let userId = appleIDCredential.user
            // 使用过授权的，可能获取不到以下三个参数
            _ = appleIDCredential.fullName?.familyName ?? ""
            _ = appleIDCredential.fullName?.givenName ?? ""
            _ = appleIDCredential.email ?? ""

            _ = appleIDCredential.authorizationCode ?? Data()
            // 用于判断当前登录的苹果账号是否是一个真实用户，取值有：unsupported、unknown、likelyReal
            // let realUserStatus = appleIDCredential.realUserStatus

            guard let identityToken = appleIDCredential.identityToken, let tokenStr = String(data: identityToken, encoding: .utf8) else {
                return
            }
            dlog("tokenStr: \(tokenStr), name: \(appleIDCredential.fullName?.givenName ?? "")")
            
            delegate?.signInAppleAuth(token: tokenStr, userId: userId, name:appleIDCredential.fullName?.givenName ?? "")

            // 服务器验证需要使用的参数
        } else if authorization.credential.isKind(of: ASPasswordCredential.classForCoder()) {
            // 这个获取的是iCloud记录的账号密码，需要输入框支持iOS 12 记录账号密码的新特性，如果不支持，可以忽略
            // Sign in using an existing iCloud Keychain credential.
            // 用户登录使用现有的密码凭证
            let passworCreddential = authorization.credential as! ASPasswordCredential
            // 密码凭证对象的用户标识 用户的唯一标识
            _ = passworCreddential.user
            // 密码凭证对象的密码
            _ = passworCreddential.password
        } else {
            // "授权信息不符合"
        }
    }

    func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
        dlog("❌ apple auth error : \(error.localizedDescription)")
    }
}

@available(iOS 13.0, *)
extension SignInAppleLogin: ASAuthorizationControllerPresentationContextProviding {
    func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
        // return UIWindow.key!
        return UIWindow.applicationKey ?? ASPresentationAnchor()
    }
}
