import CryptoJS from 'crypto-js';
/**
 * 以RecognizeBankCard为例。
 * 这里只是为了小程序端演示流程,所以将代码写在了小程序端
 * 真正上线不建议将ACCESS_KEY_ID和ACCESS_KEY_SECRET写在小程序端,会有泄漏风险,建议将请求API接口代码写到您的服务端
 * 请求银行卡识别:https://help.aliyun.com/document_detail/151893.html
 */
// 参数说明:
// miniProgramType:小程序类型,比如:微信小程序传参数:wx,支付宝传参数:my,钉钉传参数:dd,注意不要传字符串;
// callback:结果的回调
// type 1: 人物动漫化 2:人物素描化
function callRecognizeBankCard(imageURL,miniProgramType,type,callback) {
  const accessKeyId = "LTAI5tQWJ47GrfDaiUw3f5yP";
	//AccessKeySecret
  const accessKeySecret = "bMFIqdYnDw3IBZgKw37Zr5IbDqZN8k";
 //这里endpoint为API访问域名,与类目相关,具体类目的API访问域名请参考:https://help.aliyun.com/document_detail/143103.html
 let endpoint = "facebody.cn-shanghai.aliyuncs.com";
 //API Action,能力名称,请参考具体算法文档详情页中的Action参数,这里以银行卡识别为例:https://help.aliyun.com/document_detail/151893.html
 let Action = "GenerateHumanAnimeStyle";
 //API_HTTP_METHOD推荐使用POST
 const API_HTTP_METHOD = "POST";
 //API_VERSION为API版本,与类目相关,具体类目的API版本请参考:https://help.aliyun.com/document_detail/464194.html
 let API_VERSION = "2019-12-30";
 const request_ = {};
  if (type == 2) {
  	Action = "GenerateHumanSketchStyle";
  	request_["ReturnType"] = "full";
  } else if (type == 3) {
  	Action = "SegmentHDBody";
  	endpoint = "imageseg.cn-shanghai.aliyuncs.com";
  } else if (type == 4) {
      Action = "EnhanceImageColor";
  	endpoint = "imageenhan.cn-shanghai.aliyuncs.com";
  	API_VERSION = "2019-09-30";
  	request_["ImageURL"] = imageURL;
  	request_["Mode"] = "ln17_256";
  	request_["OutputFormat"] = "png";
  } else {
  	request_["AlgoType"] = "handdrawn";
  }
  //系统参数
  request_["SignatureMethod"] = "HMAC-SHA1";
  request_["SignatureNonce"] = signNRandom(); 
  request_["AccessKeyId"] = accessKeyId;
  request_["SignatureVersion"] = "1.0";
  request_["Timestamp"] = getTimestamp();
  request_["Format"] = "JSON";
  request_["RegionId"] = "cn-shanghai";
  request_["Version"] = API_VERSION;
  request_["ImageURL"] = imageURL;
  request_["Action"] = Action;
  const url = generateUrl(request_, API_HTTP_METHOD, endpoint, accessKeySecret);
  http.post({ url: url, timeout: 5000 }, function (err, result) {
      //获取结果
      callback && callback(result);
   });
   //callApiRequest(miniProgramType, request_, API_HTTP_METHOD, endpoint, accessKeySecret, callback);
};

/**
 * ========================================================================================================================
 * 封装http请求
 * ========================================================================================================================
 */
var http = {};
http.request = function (option, callback) {
  var url = option.url;
  var method = option.method;
  var data = option.data;
  var timeout = option.timeout || 0;
  //创建XMLhttpRequest对象
  var xhr = new XMLHttpRequest();
  (timeout > 0) && (xhr.timeout = timeout);
  //使用open方法设置和服务器的交互信息
  xhr.open(method, url, true);
  if (typeof data === 'object') {
    try {
      data = JSON.stringify(data);
    } catch (e) { }
  }
  //发送请求
  xhr.send(data);
  //如果请求完成,并响应完成,获取到响应数据
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4) {
      var result = xhr.responseText;
      try { result = JSON.parse(xhr.responseText); } catch (e) { }
      callback && callback(null, result);
    }
  }.bind(this);
  //延时处理
  xhr.ontimeout = function () {
    callback && callback('timeout');
    //console.log('error', '连接超时');
  };
};
//post请求
http.post = function (option, callback) {
  option.method = 'post';
  option.contentType = 'application/json;charset=UTF-8'
  this.request(option, callback);
};

//SignatureNonce随机数字
function signNRandom() {
  const Rand = Math.random()
  const mineId = Math.round(Rand * 100000000000000)
  return mineId;
};

//Timestamp
function getTimestamp() {
  let date = new Date();
  let YYYY = pad2(date.getUTCFullYear());
  let MM = pad2(date.getUTCMonth() + 1);
  let DD = pad2(date.getUTCDate());
  let HH = pad2(date.getUTCHours());
  let mm = pad2(date.getUTCMinutes());
  let ss = pad2(date.getUTCSeconds());
  return `${YYYY}-${MM}-${DD}T${HH}:${mm}:${ss}Z`;
};

//补位占位
function pad2(num) {
  if (num < 10) {
    return '0' + num;
  }
  return '' + num;
};

// 排序
function ksort(params) {
  let keys = Object.keys(params).sort();
  let newParams = {};
  keys.forEach((key) => {
    newParams[key] = params[key];
  });
  return newParams;
};

// HmacSHA1加密+base64
function createHmac(stringToSign, key) {
  const CrypStringToSign = CryptoJS.HmacSHA1(stringToSign, key);
  const base64 = CryptoJS.enc.Base64.stringify(CrypStringToSign);
  return base64;
};

//编码
function encode(str) {
  var result = encodeURIComponent(str);
  return result.replace(/!/g, '%21')
    .replace(/'/g, '%27')
    .replace(/\(/g, '%28')
    .replace(/\)/g, '%29')
    .replace(/\*/g, '%2A');
};

function sha1(stringToSign, key) {
  return createHmac(stringToSign, key);
};

function getSignature(signedParams, method, secret) {
  var stringToSign = `${method}&${encode('/')}&${encode(signedParams)}`;
  const key = secret + "&";
  return sha1(stringToSign, key);
};

//参数拼接 &
function objToParam(param) {
  if (Object.prototype.toString.call(param) !== '[object Object]') {
    return '';
  }
  let queryParam = '';
  for (let key in param) {
    if (param.hasOwnProperty(key)) {
      let value = param[key];
      queryParam += toQueryPair(key, value);
    }
  }
  return queryParam;
};

function toQueryPair(key, value) {
  if (typeof value == 'undefined') {
    return `&${key}=`;
  }
  return `&${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
};

function generateUrl(request, httpMethod, endpoint, accessKeySecret) {
  //参数中key排序
  const sortParams = ksort(request);
  //拼成参数
  const sortQueryStringTmp = objToParam(sortParams);
  const sortedQueryString = sortQueryStringTmp.substring(1);// 去除第一个多余的&符号
  //构造待签名的字符串
  const Signture = getSignature(sortedQueryString, httpMethod, accessKeySecret)
  //签名最后也要做特殊URL编码
  request["Signature"] = encodeURIComponent(Signture);
  //最终生成出合法请求的URL
  const finalUrl = "https://" + endpoint + "/?Signature=" + encodeURIComponent(Signture) + sortQueryStringTmp;
  return finalUrl;
};

//导出方法
module.exports = {
  callRecognizeBankCard: callRecognizeBankCard,
  signNRandom:signNRandom,
  getTimestamp:getTimestamp,
  generateUrl:generateUrl,
  createHmac:createHmac
}