import isEmpty from 'lodash/isEmpty';

const cacheBlockletData: Record<string, any> = {};

export function getMaster(blocklet = window.blocklet) {
  const federated = blocklet?.settings?.federated || {};
  return federated.master;
}

export function getConfig(blocklet = window.blocklet) {
  const federated = blocklet?.settings?.federated || {};
  return federated.config;
}

export function getFederatedEnabled(blocklet = window.blocklet) {
  // 适用于 webapp 下
  if (!blocklet) {
    return false;
  }
  const master = getMaster(blocklet);
  // 如果当前应用是 master，则代表未开启统一登录
  if (!master || master.appPid === blocklet.appPid) {
    return false;
  }

  const config = getConfig(blocklet);
  return config?.status === 'approved';
}

export function getSourceAppPid(blocklet = window.blocklet) {
  const master = getMaster(blocklet);
  return master?.appPid;
}

export function getFederatedApp(blocklet = window.blocklet) {
  const master = getMaster(blocklet);
  const isFederatedMode = !isEmpty(master);
  return isFederatedMode
    ? {
        appId: master.appId,
        appName: master.appName,
        appDescription: master.appDescription,
        appLogo: master.appLogo,
        appPid: master.appPid,
        appUrl: master.appUrl,
        version: master.version,
        sourceAppPid: master.appPid,
        provider: 'wallet',
      }
    : null;
}

export function getCurrentApp(blocklet = window.blocklet) {
  // 适用于 blocklet 项目
  if (blocklet) {
    return {
      appId: blocklet.appId,
      appName: blocklet.appName,
      appDescription: blocklet.appDescription,
      appLogo: blocklet.appLogo,
      appPid: blocklet.appPid,
      appUrl: blocklet.appUrl,
      // 该判断条件用于限制非统一登录模式下，当前访问的 url 与应用设置的主 url 不一致情况时有效
      // 页面的请求优先会向当前访问的域名发送，避免产生 cors 的问题
      // 而在统一登录模式下，这个值不应该提供，因为它始终会需要跨域的请求
      currentAppUrl: blocklet === window.blocklet ? window.location.origin : undefined,
      version: blocklet.version,
      // NOTICE: null 代表该值置空
      sourceAppPid: null,
      provider: 'wallet',
    };
  }
  // HACK: 适用于 blocklet-server
  if (window.env) {
    // eslint-disable-next-line no-param-reassign
    blocklet = window.env;
    return {
      appId: blocklet.appId,
      appName: blocklet.appName,
      appDescription: blocklet.appDescription,
      appUrl: blocklet.baseUrl,
      // 在 server 的登录环境下，始终提供当前的 url 作为 appUrl
      currentAppUrl: window.location.origin,
      // NOTICE: null 代表该值置空
      sourceAppPid: null,
      provider: 'wallet',
      type: 'server',
    };
  }
  return null;
}

export function getApps(blocklet: Blocklet) {
  const appList = [];

  const masterApp = getFederatedApp(blocklet);
  const currentApp = getCurrentApp(blocklet);
  const federatedEnabled = getFederatedEnabled(blocklet);

  if (currentApp) {
    appList.push(currentApp);
  }
  if (masterApp && masterApp?.appId !== currentApp?.appId && federatedEnabled) {
    appList.push(masterApp);
  }
  // NOTICE: masterApp 应该排在前面
  return appList.reverse();
}

export async function getBlockletData(appUrl: string, force = false): Promise<Blocklet | null> {
  if (!force && cacheBlockletData[appUrl]) {
    return cacheBlockletData[appUrl];
  }
  try {
    const url = new URL('__blocklet__.js', appUrl);
    url.searchParams.set('type', 'json');
    const res = await fetch(url.href);
    const jsonData = await res.json();
    cacheBlockletData[appUrl] = jsonData;
    return jsonData;
  } catch (err) {
    console.error(`Failed to get blocklet data: ${appUrl}`, err);
    return null;
  }
}
