/* 引入 interface.uts 文件中定义的变量 */
import { GoogleLoginOptions, GoogleLogin, GoogleLogoutOptions, GoogleLogout, GoogleLoginSuccess } from '../interface.uts';
/* 引入 unierror.uts 文件中定义的变量 */
import { GoogleLoginFailImpl } from '../unierror';

import CoroutineScope from 'kotlinx.coroutines.CoroutineScope';
import Dispatchers from 'kotlinx.coroutines.Dispatchers';
import launch from 'kotlinx.coroutines.launch';

import SystemClock from 'android.os.SystemClock';
import Base64 from 'android.util.Base64';
import CredentialManager from 'androidx.credentials.CredentialManager';
import ClearCredentialStateRequest from 'androidx.credentials.ClearCredentialStateRequest';
import Credential from 'androidx.credentials.Credential';
import GetCredentialRequest from 'androidx.credentials.GetCredentialRequest';
import GetCredentialResponse from 'androidx.credentials.GetCredentialResponse';
import GetGoogleIdOption from 'com.google.android.libraries.identity.googleid.GetGoogleIdOption';
import GoogleIdTokenCredential from 'com.google.android.libraries.identity.googleid.GoogleIdTokenCredential';

export type CallKotlinLoginOptions = {
	success : (data : GoogleLoginSuccess | null) => void
	fail : (ex : Exception | null) => void
}

export type CallKotlinLogOutOptions = {
	complete : (ex : Exception | null) => void
}

/**
 * google logout logic
 */
export const googleLogout : GoogleLogout = function (option : GoogleLogoutOptions) {

	let options = {
		complete: (ex : Exception | null) => {
			console.log("fail", ex)
			if(ex == null){
				// 成功
				option.success?.("")
				option.complete?.("")
				option.success = null
				option.complete = null
			}else{
				// 未知错误
				const err = new GoogleLoginFailImpl(9010099);
				option.fail?.(err)
				option.complete?.(err)
				option.fail = null;
				option.complete = null;
			}
		},
	} as CallKotlinLogOutOptions
	
	let credentialManager = CredentialManager.create(UTSAndroid.getUniActivity()!)
	NativeCode.requestLogout(credentialManager, options);

}

/**
 * android google login 实现逻辑
 */
export const googleLogin : GoogleLogin = function (options : GoogleLoginOptions) {

	if (UTSAndroid.getUniActivity() == null || UTSAndroid.getUniActivity()!.isFinishing()) {
		const err = new GoogleLoginFailImpl(9010001);
		options.fail?.(err)
		options.complete?.(err)
		options.fail = null;
		options.complete = null;
		return;
	}

	let credentialManager = CredentialManager.create(UTSAndroid.getUniActivity()!)
	let googleIdOption = GetGoogleIdOption.Builder()
		.setServerClientId(options.serverClientId)  // Web 客户端 ID
		.setFilterByAuthorizedAccounts(false)  // 仅显示已授权账户
		.setAutoSelectEnabled(true)  // 自动选择唯一账户
		.setNonce(SystemClock.uptimeMillis().toString())  // 防止重放攻击
		.build()

	let request = GetCredentialRequest.Builder()
		.addCredentialOption(googleIdOption)
		.build()
	/**
	 * 调用kotlin代码
	 */
	let option = {
		success: (data : GoogleLoginSuccess | null) => {

			if (data == null) {
				// 未知错误
				const err = new GoogleLoginFailImpl(9010099);
				options.fail?.(err)
				options.complete?.(err)
				options.fail = null;
				options.complete = null;
				return
			}

			options.success?.(data)
			options.complete?.(data)
			options.success = null;
			options.complete = null;

		},
		fail: (ex : Exception | null) => {

			if (ex == null) {
				// 成功返回了凭证，但是凭证类型不是 google Id token。 暂不支持
				const err = new GoogleLoginFailImpl(9010003);
				options.fail?.(err)
				options.complete?.(err)
				options.fail = null;
				options.complete = null;
				return
			}
			
			let err:GoogleLoginFailImpl
			if ("androidx.credentials.exceptions.NoCredentialException" == ex.javaClass.name) {
				/**
				 * 证书签名错误
				 */
				err = new GoogleLoginFailImpl(9010004);
			}else if("androidx.credentials.exceptions.GetCredentialProviderConfigurationException" == ex.javaClass.name) {
				/**
				 * 系统组件缺失
				 */
				err = new GoogleLoginFailImpl(9010005);
			}
			else if ("androidx.credentials.exceptions.GetCredentialCancellationException" == ex.javaClass.name) {
				console.log(ex)
				/**
				 * 通常是因为serverclient配置错误导致
				 */
				err = new GoogleLoginFailImpl(9010002);
			}else{
				err = new GoogleLoginFailImpl(9010099);
			}
			
			options.fail?.(err)
			options.complete?.(err)
			options.fail = null;
			options.complete = null;
			return
		},
	} as CallKotlinLoginOptions

	NativeCode.requestLogin(credentialManager, request, option);

}