import { joinURL } from 'ufo';
import { getFederatedEnabled, getMaster } from '@arcblock/ux/lib/Util/federated';

import { createAxios, sleep } from '../../utils';
import { BLOCKLET_SERVICE_PATH_PREFIX } from '../../constant';

const api = createAxios();

/**
 * 获取 master 的 token
 * @returns {Promise<{sessionToken: string; refreshToken: string;}>}
 */
async function getMasterToken() {
  const url = joinURL(BLOCKLET_SERVICE_PATH_PREFIX, '/api/federated/loginMaster');
  const { data } = await api.post(url);
  return data;
}

// eslint-disable-next-line require-await
export async function mountFederatedIframe({ mode, refreshToken = '', blocklet }) {
  const master = getMaster(blocklet);
  return new Promise((resolve) => {
    if (!['login', 'logout'].includes(mode)) {
      resolve();
      return;
    }

    const iframe = document.createElement('iframe');
    iframe.style.display = 'none';
    iframe.onload = async () => {
      // HACK: 即使当前页面已经 Load 成功，也强制等待 500ms，确保不会产生边缘情况的问题
      await sleep(500);
      document.body.removeChild(iframe);
      resolve();
    };
    iframe.src = joinURL(
      master.appUrl,
      BLOCKLET_SERVICE_PATH_PREFIX,
      `functional/federated?mode=${mode}&refreshToken=${refreshToken}`
    );
    document.body.appendChild(iframe);
  });
}

/**
 * @deprecated no longer used
 */
export async function loginFederatedMaster(params = {}, { fetchToken = true, blocklet } = {}) {
  const enableFederated = getFederatedEnabled();
  if (!enableFederated) {
    console.warn('Federated not enabled');
    return null;
  }
  /**
   * @type {string}
   */
  let sessionToken;
  /**
   * @type {string}
   */
  let refreshToken;

  if (fetchToken) {
    ({ sessionToken, refreshToken } = await getMasterToken());
  }

  const master = getMaster(blocklet);
  const url = joinURL(master.appUrl, BLOCKLET_SERVICE_PATH_PREFIX, '/api/federated/login');
  const options = { withCredentials: true };

  if (sessionToken) {
    options.headers = {
      Authorization: `Bearer ${sessionToken}`,
    };
  }

  const { data } = await api.post(url, params, options);
  if (refreshToken) {
    await mountFederatedIframe({ mode: 'login', refreshToken, blocklet });
  }
  return data;
}
