/**
 * 函数二次验证 hook
 */
import { translate } from '@arcblock/ux/lib/Locale/util';
import { LOGIN_PROVIDER } from '@blocklet/constant';
import { toBase64 } from '@ocap/util';
import { translations } from '../libs/locales';

export default function useVerify({ state, locale, connectApi }) {
  const { user } = state;

  // 是否要使用 passkey 进行验证
  const connectedAccounts = user?.connectedAccounts || [];
  const hasPasskey = connectedAccounts.some((x) => x.provider === LOGIN_PROVIDER.PASSKEY);
  const hasEmail = connectedAccounts.some((x) => x.provider === LOGIN_PROVIDER.EMAIL);
  const hasGithub = connectedAccounts.some((x) => x.provider === LOGIN_PROVIDER.GITHUB);
  const hasGoogle = connectedAccounts.some((x) => x.provider === LOGIN_PROVIDER.GOOGLE);
  const hasApple = connectedAccounts.some((x) => x.provider === LOGIN_PROVIDER.APPLE);
  const passkeyBehavior = hasPasskey ? 'only-existing' : 'none';
  const enabledConnectTypes = ['web', 'mobile'];

  if (hasEmail) {
    enabledConnectTypes.push('email');
  }

  if (hasGithub) {
    enabledConnectTypes.push('github');
  }

  if (hasGoogle) {
    enabledConnectTypes.push('google');
  }

  if (hasApple) {
    enabledConnectTypes.push('apple');
  }

  const t = (key, data = {}) => {
    return translate(translations.verify, key, locale, 'en', data);
  };

  return (options = {}) => {
    const { payload, ...rest } = options.extraParams || {};
    const extraParams = {
      payload: toBase64(JSON.stringify({ action: options.operation || 'destroy-self', input: rest.input || {} })),
      ...(rest || {}),
    };
    return new Promise((resolve, reject) => {
      connectApi.open({
        locale,
        action: options.action || 'destroy-self', // 每次都需要验证的
        forceConnected: true,
        saveConnect: false,
        autoConnect: false,
        className: 'connect',
        checkTimeout: 10 * 60 * 1000,
        passkeyBehavior,
        enabledConnectTypes,
        messages: options.messages || {
          title: t('title'),
          scan: t('scan'),
          confirm: t('confirm'),
          success: t('success'),
        },
        extraParams,
        onSuccess: (result, decrypt = (x) => x) => {
          resolve({ result, input: rest.input, sessionId: decrypt(result.destroySessionId) });
        },
        onClose: () => {
          reject(new Error(t('abort')));
          connectApi.close();
        },
      });
    });
  };
}
