const system = require("../system");
const moment = require('moment')
const settings = require("../../config/settings");
const md5 = require("MD5");

const axios = require('axios');

class ServiceBase {
  constructor() {
    this.restClient = system.getObject("util.restClient");
    this.synlogDao = system.getObject("db.log.synlogDao");
    this.micro = system.microsetting();
  }

  async getEncryptStr(str) {
    if (!str) {
      throw new Error("字符串不能为空");
    }
    var md5 = this.md5(str + "_" + settings.salt);
    return md5.toString().toLowerCase();
  }

  /**
   * 验证签名
   * @param {*} params 要验证的参数
   * @param {*} app_key 应用的校验key
   */
  async verifySign(params, app_key) {
    if (!params) {
      return system.getResult(null, "请求参数为空");
    }
    if (!params.sign) {
      return system.getResult(null, "请求参数sign为空");
    }
    var signArr = [];
    var keys = Object.keys(params).sort();
    if (keys.length == 0) {
      return system.getResult(null, "请求参数信息为空");
    }
    for (let k = 0; k < keys.length; k++) {
      const tKey = keys[k];
      if (tKey != "sign" && params[tKey] && !(params[tKey] instanceof Array)) {
        signArr.push(tKey + "=" + params[tKey]);
      }
    }
    if (signArr.length == 0) {
      return system.getResult(null, "请求参数组装签名参数信息为空");
    }
    var resultSignStr = signArr.join("&") + "&key=" + app_key;
    var resultTmpSign = md5(resultSignStr).toUpperCase();
    if (params.sign != resultTmpSign) {
      return system.getResult(null, "返回值签名验证失败");
    }
    return system.getResultSuccess();
  }
  /**
   * 创建签名
   * @param {*} params 要验证的参数
   * @param {*} app_key 应用的校验key
   */
  async createSign(params, app_key) {
    if (!params) {
      return system.getResultFail(-310, "请求参数为空");
    }
    var signArr = [];
    var keys = Object.keys(params).sort();
    if (keys.length == 0) {
      return system.getResultFail(-330, "请求参数信息为空");
    }
    for (let k = 0; k < keys.length; k++) {
      const tKey = keys[k];
      if (tKey != "sign" && params[tKey] && !(params[tKey] instanceof Array)) {
        signArr.push(tKey + "=" + params[tKey]);
      }
    }
    if (signArr.length == 0) {
      return system.getResultFail(-350, "请求参数组装签名参数信息为空");
    }
    var resultSignStr = signArr.join("&") + "&key=" + app_key;
    var resultTmpSign = md5(resultSignStr).toUpperCase();
    return system.getResultSuccess(resultTmpSign);
  }
  /**
   * 验证参数信息不能为空
   * @param {*} params 验证的参数
   * @param {*} verifyParamsCount 需要验证参数的数量，如至少验证3个，则传入3
   * @param {*} columnList 需要过滤掉的验证参数列表，格式:[]
   */
  async verifyParams(params, verifyParamsCount, columnList) {
    if (!params) {
      return system.getResult(null, "请求参数为空");
    }
    if (!columnList) {
      columnList = [];
    }
    var keys = Object.keys(params);
    if (keys.length == 0) {
      return system.getResult(null, "请求参数信息为空");
    }
    if (keys.length < verifyParamsCount) {
      return system.getResult(null, "请求参数不完整");
    }
    var tResult = system.getResultSuccess();
    for (let k = 0; k < keys.length; k++) {
      const tKeyValue = keys[k];
      if (columnList.length == 0 || columnList.indexOf(tKeyValue) < 0) {
        if (!tKeyValue) {
          tResult = system.getResult(null, k + "参数不能为空");
          break;
        }
      } //白名单为空或不在白名单中，则需要验证不能为空
    }
    return tResult;
  }
  async apiCallWithAk(url, params) {
    var acckapp = await this.cacheManager["ApiAccessKeyCache"].cache(settings.appKey);
    var acck = acckapp.accessKey;
    //按照访问token
    var restResult = await this.restClient.execPostWithAK(params, url, acck);
    if (restResult) {
      if (restResult.status == 0) {
        var resultRtn = restResult.data;
        return resultRtn;
      } else {
        await this.cacheManager["ApiAccessKeyCache"].invalidate(settings.appKey);
        return null;
      }
    }
    return null;
  }
  /*
  返回20位业务订单号
  prefix：业务前缀
  */
  async getBusUid(prefix) {
    prefix = (prefix || "");
    if (prefix) {
      prefix = prefix.toUpperCase();
    }
    var prefixlength = prefix.length;
    var subLen = 8 - prefixlength;
    var uidStr = "";
    if (subLen > 0) {
      uidStr = await this.getUidInfo(subLen, 60);
    }
    var timStr = moment().format("YYYYMMDDHHmm");
    return prefix + timStr + uidStr;
  }
  /*
  len：返回长度
  radix：参与计算的长度，最大为62
  */
  async getUidInfo(len, radix) {
    var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''); //长度62，到yz长度为长36
    var uuid = [],
      i;
    radix = radix || chars.length;
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      var r;
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }
    return uuid.join('');
  }

  handleDate(row, fields, pattern, addHours) {
    pattern = pattern || "YYYY-MM-DD HH:mm";
    if (!row) {
      return;
    }
    for (var field of fields) {
      if (row[field]) {
        if (addHours) {
          row[field] = moment(row[field]).add(addHours, "hours").format(pattern);
        } else {
          row[field] = moment(row[field]).format(pattern);
        }

      }
    }
  }

  addWhereTime(where, field, begin, end) {
    if (!begin && !end) {
      return;
    }

    if (begin && end) {
      where[field] = {
        [this.db.Op.between]: [begin, end]
      };
    } else if (begin && !end) {
      where[field] = {
        [this.db.Op.gte]: begin
      };
    } else if (!begin && end) {
      where[field] = {
        [this.db.Op.lte]: end
      };
    }
  }

  async callms(sveName, apiName, params) {
    var reqUrl = this.micro[sveName];
    console.log(reqUrl, "-----------------------------");

    if (!reqUrl) {
      return system.getResult(null, "未找到【" + sveName + "】服务，请检查settings文件是否存在");
    }
    if (!apiName) {
      return system.getResult(null, "apiName不能为空");
    }
    try {
      var params = {
        "action_process": "sijibao",
        "action_type": apiName,
        "action_body": params || {},
      }

      if(settings.env == 'dev') {
        let rs = await axios({
          method: 'post',
          url: reqUrl,
          data: params
        });

        console.log(rs);
        return rs.data;
      }
      var rs = await this.restClient.execPost(params, reqUrl);
      if (rs && rs.stdout) {
        return JSON.parse(rs.stdout);
      }
      return system.getResult(null, rs);
    } catch (error) {
      console.log(error);
      this.logCtl.error({
        optitle: "微服务请求失败",
        op: "sveName = " + sveName + "; apiName = " + apiName,
        content: "params = " + JSON.stringify(params),
        clientIp: ""
      });
      return system.getResult(null, error.message);
    }
  }

  async callApi(url, data, name) {
    let res;
    let log = await this.addSynLog(url, data, name);
    try {
      res = await axios({
        method: 'post',
        url: url,
        data: data
      });
      if(log) {
        log.apiRes = JSON.stringify(res.data);
        log.save();
      }
      return res.data;
    } catch (e) {
      console.log(e);
    }
    return res.data;
  }

  async addSynLog(url, data, name) {
    try {
      return await this.synlogDao.create({
        apiUrl: url,
        apiName: name,
        apiReq: JSON.stringify(data),
        apiRes: "",
      });
    } catch (e) {
      console.log(e)
    }
    return null;
  }

  trim(o) {
    if (!o) {
      return "";
    }
    return o.toString().trim();
  }
}
module.exports = ServiceBase;
