import {
  prefixPagePath,
  serviceReportUrl,
  serviceReportCloudMonitorUrl,
  checkCertifyValidUrl,
  authAndApplyFaceUrl,
  authCertTypeUrl,
  dynamicPageName,
} from './constants';
import { getServerTime, getSystemInfo, getAuthUser, startAPVerify, getAppId } from './jsapi';
import request, { getTicket } from './request';
import monitor from './alipayLogger';
import queryString from 'query-string';

export * from './request';
export * from './jsapi';
export * from './registerHooks';
export * from './constants';
export * from './service';

export function sleep(timeout = 1000) {
  return new Promise((resolve) => {
    setTimeout(resolve, timeout);
  });
}

// 验证邮箱是否合法
export function verifyEmail(email) {
  const reg = new RegExp('^[a-z0-9]+([._\\-]*[a-z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$', 'img');
  return !email || !reg.test(email);
}

export function debounce(fn, delay = 0, ctx) {
  let timer;
  return function _(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(ctx, args);
    }, delay);
  };
}

export function throttle(fn, wait = 800) {
  let start = Date.now();
  return function () {
    const ctx = this;
    // eslint-disable-next-line prefer-rest-params
    const args = arguments;
    const now = Date.now();
    if (now - start >= wait) {
      fn.apply(ctx, args);
      start = now;
    }
  };
}

async function jump(payload) {
  try {
    if (payload && payload.type === 'navigateBack') {
      my.navigateBack({
        delta: payload.delta || 1,
      });
    }
    if (payload && payload.isToService) {
      return this.dispatchGlobal('handleJumpService', payload);
    }
    if (!payload || !payload.url) return false;
    if (!payload.isToService) return my.navigateTo({ url: payload.url });
  } catch (error) {
    console.error(error);
  }
}

export const navigateTo = throttle(jump);

export function jumpPageLoginFailure({ accessDenyBack, accessDenyUrl }) {
  if (accessDenyBack === 'back') {
    my.navigateBack();
    return;
  }
  if (accessDenyBack === 'page') {
    let pageUuid = '';
    let url = '';
    if (accessDenyUrl.indexOf(':') > -1) {
      pageUuid = accessDenyUrl.split(':')[1];
      url = `${prefixPagePath}/${dynamicPageName}/index?pageUuid=${pageUuid}`;
    } else {
      url = accessDenyUrl;
    }
    my.redirectTo({
      url,
    });
  }
}

async function checkTimeExpire(time) {
  if (!time) return false;
  const [err, res] = await getServerTime();
  const currentTime = err ? new Date().getTime() : +res.time;
  return time < currentTime;
}

export function isObj(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

export function toUrl(obj) {
  if (!obj || !isObj(obj)) {
    return '';
  }
  return Object.keys(obj).reduce((p, v, i) => `${p}${i ? '&' : ''}${v}=${obj[v]}`, '?');
}

export function paramsParse(params) {
  if (typeof params !== 'string') return {};
  const search = params.split('?')[1];
  const replaceHandler = function (key, value) {
    return key === '' ? value : decodeURIComponent(value);
  };
  return search ? JSON.parse(`{"${search.replace(/&/g, '","').replace(/=/g, '":"')}"}`, replaceHandler) : {};
}


export function parseUrlQuery(url, noDecodeURI) {
  if (!url) return {};
  const search = url.substring(url.lastIndexOf('?') + 1);
  const reg = /([^?&=]+)=([^?=&]*)/g;
  const hash = {};
  search.replace(reg, (match, $1, $2) => {
    const key = decodeURIComponent($1);
    const value = decodeURIComponent($2);
    if (!noDecodeURI) {
      hash[key] = value;
    } else {
      hash[$1] = $2;
    }
    return match;
  });
  return hash;
}

export function replaceUrlParam(url, key, value) {
  const reg = new RegExp(`${key}=([^&]*)`, 'i');
  const result = url.replace(reg, `${key}=${value}`);
  return result;
}

export function getUrlProtocal(url) {
  return url.split(':')[0].toLowerCase();
}
export async function checkTicketExpire() {
  // eslint-disable-next-line no-undef
  const app = getApp();
  const { expiresTime } = app.globalData.ticketData;
  const isExpire = await checkTimeExpire(expiresTime);
  if (!isExpire) {
    return [undefined, isExpire];
  }
  const result = await getTicket();
  return result;
}

export async function serviceReportCM(payload) {
  try {
    const sysInfo = await getSystemInfo();
    // eslint-disable-next-line
    const page = getCurrentPages().pop().__proto__.route || '';
    const data = {
      sysInfo: JSON.stringify(sysInfo),
      page,
      ...payload,
    };
    const result = await request({
      url: serviceReportCloudMonitorUrl,
      data,
    });
    return result;
  } catch (error) {
    return error;
  }
}

// 新: 上报光华平台
export async function reportCmPV({ title, query, tag = 'h5SE_YL' } = {}) {
  if (!title) return; // title是必填项
  const url = getCurrentPages()[getCurrentPages().length - 1].route;
  let { appId } = getApp().globalData;
  if (!appId) {
    appId = getAppId();
  }
  let encodedUrl;
  if (query && Object.keys(query).length > 0) {
    encodedUrl = encodeURIComponent(`${url}?${queryString.stringify(query)}`);
  } else {
    encodedUrl = encodeURIComponent(`${url}`);
  }
  const myUrl = `alipays://platformapi/startapp?appId=${appId}&page=${encodedUrl}`;
  monitor._lgPV({
    page: title,
    url,
    c1: tag,
    c2: myUrl,
  });
}

export async function serviceReport(payload) {
  try {
    const sysInfo = await getSystemInfo();
    const data = {
      sysInfo: JSON.stringify(sysInfo),
      ...payload,
    };
    const result = await request({
      url: serviceReportUrl,
      data,
    });
    return result;
  } catch (error) {
    return error;
  }
}


export const usualErrMsg = '抱歉，系统异常，请稍后再试';

export function getStorage(key) {
  return new Promise((resolve) => {
    my.getStorage({
      key,
      success(res) {
        resolve(res.data);
      },
      fail() {
        resolve(null);
      },
    });
  });
}


export function setStorage(key, data) {
  return new Promise((resolve) => {
    my.setStorage({
      key,
      data,
      success() {
        resolve(true);
      },
      fail() {
        resolve(false);
      },
    });
  });
}

export function getSharePath(options = {}) {
  // eslint-disable-next-line no-undef
  const currentPages = getCurrentPages();
  // eslint-disable-next-line no-proto
  let pageName = JSON.stringify(currentPages[currentPages.length - 1].__proto__.route);
  pageName = pageName.replace(/^"|"$/g, '');
  let query = '';
  if (options.pageUuid) {
    query = `${query}&pageUuid=${options.pageUuid}`;
  }
  if (options.pageCode) {
    query = `${query}&pageCode=${options.pageCode}`;
  }
  if (query.length > 0) {
    query = query.replace(/^&/, '?');
  }
  return `${pageName}${query}`;
}

export async function checkCertifyTimeout(data) {
  const [err, res] = await request({
    url: checkCertifyValidUrl,
    data,
    isShowLoadig: true,
  });
  return [err, res];
}

export async function userIdentity(data) {
  const [err, res] = await getAuthUser();
  if (err) return [err, null];
  data.authCode = res.authCode;
  const [error, response] = await request({
    url: authAndApplyFaceUrl,
    data,
    isShowLoadig: true,
  });
  if (error) return [error, null];
  const result = await startAPVerify(response.certifyId, response.certifyUrl);
  return result;
}

export async function certIdentity(data) {
  const [error, result] = await request({
    url: authCertTypeUrl,
    data,
    isShowLoadig: true,
  });
  if (error) return [error, null];
  return [null, result];
}

// 设置全局传的参数, 可以传对象{name1: value, name2: value2}
export function setPagesQuery(params) {
  // eslint-disable-next-line no-undef
  const app = getApp();
  Object.keys(params).forEach(item => {
    app.globalData.pagesQuery[item] = params[item];
  });
}

// 移除全局传的参数, 可以传数组, [name]
export function removePagesQuery(params) {
  // eslint-disable-next-line no-undef
  const app = getApp();
  Object.keys(params).forEach(() => {
    delete app.globalData.pagesQuery.item;
  });
}

// 获取全局传的参数
export function getPagesQuery(name) {
  // eslint-disable-next-line no-undef
  const app = getApp();
  return app.globalData.pagesQuery[name];
}

/*
* 获取当前页面的store
* */
export function getCurrentStore() {
  const pages = getCurrentPages();
  const currentRoute = pages[pages.length - 1] || {};
  return currentRoute.$store.storeInstance || {};
}

/*
* 获取全局的state
* */
export function getGlobalState() {
  const { $store = {} } = getCurrentStore();
  return $store.$global.globalStoreConfig.state;
}

/*
* 获取store里面的用户信息
* */
export function getUserInfoByStore() {
  const { userInfo } = getGlobalState();
  return userInfo || {};
}

/*
* 获取accessMode
* 兼容以前老的字符串的accessMode
* */
export function getAccessMode(accessMode) {
  if (typeof accessMode !== 'string') return accessMode;
  const oldMode = {
    none: { none: true },
    cert: { cert: true },
    login: { login: true },
    identity: { identity: true },
    realName: { realName: true },
    customer: { customer: true },
  };
  return oldMode[accessMode] || {};
}

// 记录时间节点
export const seq = (function* () {
  let timeline = 'startApp';
  let prev = Date.now();
  while (true) {
    const now = Date.now();
    // eslint-disable-next-line no-console
    timeline = yield console.log(`${timeline}: ${now - prev}ms`);
    prev = now;
  }
})();

export function stringifyQuery(query = {}) {
  let str = '';
  Object.keys(query).forEach(key => {
    str = `${str}&${key}=${encodeURIComponent(query[key])}`;
  });
  str = str.replace(/^&/, '?');
  return str;
}
