import { CodeError } from "./common-helpers/CodeError";
import { Errors as ERRORS } from "./common-helpers/errors";
import { evalJsScript, jsonp } from "@grace/built-in";
import axios from "axios";

const isProd = location.href.indexOf('.com.cn/projectx') >= 0;

let pxTokenKeyValid = false;

let getting = false;
const _queue = [];

/**
 * 获取token
 * @ctype PROCESS
 * @description 获取星速台防刷token
 * @returns
 * token string token
 * @example 一般用法
 * const token = await getPxToken().catch(e=>{
 *   console.log('获取失败，失败原因:', e.message)
 * })
 * if(token){
 *   console.log('获取成功，token：', token)
 * }
 */
export async function getPxToken() {
  if (!isProd) {
    console.log('[Mock] getPxToken');
    return 'test_token';
  }

  return new Promise((resolve, reject) => {
    _queue.push({resolve, reject});
    setTimeout(_getPxToken, 10);
  });
}

async function _getPxToken() {
  if (getting) {
    return;
  }
  if (_queue.length > 0) {
    const p = _queue.shift();
    try {
      getting = true;
      const token = await _tryGetPxToken();
      p.resolve(token);
      getting = false;
      setTimeout(_getPxToken, 10);
    } catch (e) {
      getting = false;
      p.reject(e);
    }
  }
}

async function _tryGetPxToken() {
  let token, err;
  for (let i = 0; i < 2; i++) {
    try {
      token = await _doGetPxToken();
      break;
    } catch (e) {
      err = e;
      invalidPxTokenKey();
    }
  }

  if (token) {
    return token;
  } else {
    throw err;
  }
}

async function _doGetPxToken() {
  if (!pxTokenKeyValid) {
    await refreshPxTokenKey();
  }
  return getToken();
}

/**
 * 让tokenKey失效
 * @ctype PROCESS
 * @description 比如活动页跳转到其他星速台页面，回来的时候就需要监听history然后让tokenKey失效
 * @example 一般用法
 * invalidPxTokenKey()
 */
export function invalidPxTokenKey() {
  pxTokenKeyValid = false;
}

async function refreshPxTokenKey() {
  if (!isProd) {
    pxTokenKeyValid = true;
    console.log('[Mock] refreshPxTokenKey');
    return;
  }
  pxTokenKeyValid = false;
  await jsonp('getTokenKey?_t=' + Date.now());
  pxTokenKeyValid = true;
}

async function getToken() {
  const resp = await axios.get('getToken');

  if (resp.data.success) {
    evalJsScript(resp.data);
    const token = window['ohjaiohdf']();
    if (token) {
      return token;
    }

    throw new CodeError(ERRORS.GET_PX_TOKEN_FAILED, '获取token失败，请查明key是否被覆盖');
  } else {
    throw new CodeError(resp);
  }
}
