import { useMemoizedFn, useReactive } from 'ahooks';
import { getConfig, getFederatedEnabled, getMaster } from '@arcblock/ux/lib/Util/federated';
import noop from 'lodash/noop';

import { loginFederatedMaster } from '../libs/federated';

const translations = {
  zh: {
    notFoundFederatedInfo: '未发现统一登录的信息',
    autoLoginFederatedFailed: '自动登录统一登录账号失败',
    manualLoginFederatedFailed: '手动登录统一登录账号失败',
  },
  en: {
    notFoundFederatedInfo: 'No federated login info detected',
    autoLoginFederatedFailed: 'Auto login federated account failed',
    manualLoginFederatedFailed: 'Manual login federated account failed',
  },
};

export default function useFederated({ locale, handleLoginResult, login, handleRefreshUser }) {
  const state = useReactive({
    federatedMaster: null,
  });
  const federatedEnabled = getFederatedEnabled();
  const master = getMaster();
  const config = getConfig();

  /**
   * @deprecated no longer used
   */
  const loginFederated = useMemoizedFn(
    async (callback = noop, extraParams = {}, options = {}) => {
      // @compatible: 兼容旧的传递 origin 的方式
      if (typeof options === 'string') {
        // eslint-disable-next-line no-param-reassign
        options = { origin: options };
      }
      // eslint-disable-next-line prefer-const
      let { mode = 'auto', ...params } = extraParams;
      if (options.mode) {
        mode = options.mode;
      }
      // @compatible end

      if (mode === 'auto') {
        if (!federatedEnabled) {
          // NOTE: 这里的错误仅展示在控制台，不需要展示给用户看
          throw new Error(translations[locale].notFoundFederatedInfo);
        }
        try {
          // 自动登录的前提是：master 已经登录成功，这里需要通过 master 拿到 member 的登录 token
          // FIXME: @zhanghan 当 connect 组件使用不同的 baseUrl 时，不应该直接从 window.blocklet 去取值
          const data = await loginFederatedMaster({ appId: globalThis.blocklet.appId }, { fetchToken: false });
          handleLoginResult({ ...data, encrypted: false });
          await handleRefreshUser({ showProgress: true });
          callback();
        } catch (err) {
          const errMessage = err?.response ? err.response?.data : err?.message;
          callback(errMessage || translations[locale].autoLoginFederatedFailed);
        }
      } else if (mode === 'manual') {
        try {
          login(
            async () => {
              await loginFederatedMaster(
                // FIXME: @zhanghan 当 connect 组件使用不同的 baseUrl 时，不应该直接从 window.blocklet 去取值
                { appId: globalThis.blocklet.appId, onlyWriteCookie: true }
              );
              callback();
            },
            { ...params },
            options
          );
        } catch (err) {
          const errMessage = err?.response ? err.response?.data : err?.message;
          callback(errMessage || translations[locale].autoLoginFederatedFailed);
        }
      }
    },
    [handleRefreshUser, login, locale, handleLoginResult]
  );

  return {
    master,
    config,
    federatedMaster: state.federatedMaster,
    federatedEnabled,
    loginFederated,
    loginFederatedMaster,
  };
}
