const system = require("../../../system");
const ServiceBase = require("../../svems.base");
const settings = require("../../../../config/settings");
const fs = require("fs");
const xlsx = require('node-xlsx');

class TradeService extends ServiceBase {
  constructor() {
    super();
    this.businessmenSve = system.getObject("service.business.businessmenSve");
    this.merchantSve = system.getObject("service.saas.merchantSve");
  }

  async parseItems(params) {
    // 读取excel
    let dataList = await this.readItems(params.fileUrl, params.fileName);

    // 验证字段
    let error = await this.checkDataList(dataList);

    // 计算预计付款基恩
    let result = await this.countAmt(dataList, params.saas_merchant_id);

    // 封装返回对象
    result.error = error;
    result.dataList = dataList;
    return system.getResultSuccess(result);
  }
  async countAmt(dataList, saas_merchant_id) {
    let result = {actual_amt:0, deduct_amt:0, service_tax:0};
    if(!dataList) {
      return result;
    }

    // 获取商户签约信息
    let info = await this.merchantSve.signInfo({id: saas_merchant_id}) || {};
    info = info.data || {};

    // 服务费，这里已经处理了分转元，不用在处理
    let service_rate = info.trans_service_rate;

    // 实发总数
    let totalAmt = 0;
    for (let data of dataList) {
      totalAmt = totalAmt + Number(data.amt || 0);
    }

    // 服务费
    result.service_tax = parseFloat((totalAmt * service_rate) / 100).toFixed(2);
    // 总实发
    result.actual_amt = parseFloat(totalAmt).toFixed(2);
    // 总扣款
    result.deduct_amt = parseFloat(Number(result.actual_amt) + Number(result.service_tax)).toFixed(2);
    return result;
  }

  async readItems(fileUrl, fileName) {
    let dataList = [];
    let filePath = settings.localpath() + "saas_xgg_trade_order_" + this.trim(fileName) + ".xlsx";
    try {
      // await this.downloadFile(params.url, filePath);
      await this.restClient.execDownload2(fileUrl, filePath);

      let sheets = xlsx.parse(filePath);
      fs.unlinkSync(filePath);

      if (!sheets || sheets.length == 0) {
        return system.getResult(null, "打款文件无数据")
      }
      let sheet = sheets[0];
      if (!sheet || !sheet.data || sheet.data.length == 0) {
        return system.getResult(null, "打款文件无数据")
      }
      let rows = sheet.data;
      let dataList = [];
      for (let idx = 6; idx < rows.length; idx++) {
        var data = {
          errors: []
        };

        let cells = rows[idx];
        let cellLength = cells.length;

        if (cellLength == 0) {
          continue;
        }
        if (cellLength < 7) {
          data.errors.push("缺少数据, 列数不全");
          continue;
        }
        data.acc_name = this.trim(cells[1]);
        data.credit_code = this.trim(cells[2]).toUpperCase();
        data.acc_no = this.trim(cells[3]);
        data.open_bank = this.trim(cells[4]);
        data.amt = this.trim(cells[5]);
        data.remark = this.trim(cells[6]);
        dataList.push(data);
      }

      return dataList;
    } catch (error) {
      console.log(error);
      return system.getResult(null, "excel解析出错")
    }
  }

  async checkDataList(dataList) {
    let error = false;
    if (!dataList || dataList.length == 0) {
      return system.getResult(null, "打款文件无数据")
    }

    // 统一社会信用代码获取
    let creditCodes = [];
    for (let data of dataList) {
      creditCodes.push(data.credit_code);
    }
    let creditCodeMap = await this.businessmenSve.mapByCreditCodes({creditCodes: creditCodes, attrs: "credit_code"});
    for (let data of dataList) {
      this.checkField(data, "acc_name", {name: "收款户名", is_require: true, maxLen: 64});
      let bm = creditCodeMap[data.credit_code];
      if (!bm) {
        data.errors.push(`统一社会信用代码[${data.credit_code}]不存在`);
      }
      this.checkField(data, "credit_code", {name: "个体户统一信用代码", is_require: true, eqLen: 18});
      this.checkField(data, "acc_no", {name: "收款账号", is_require: true, maxLen: 30, is_number: true});
      this.checkField(data, "open_bank", {name: "开户银行全称", maxLen: 100});
      this.checkField(data, "amt", {name: "商户请求打款金额", is_require: true, maxLen: 100, is_number: true});
      this.checkField(data, "remark", {name: "备注", maxLen: 100});

      if (!error && data.errors.length > 0) {
        error = true;
      }
    }
    return error;
  }

  checkField(data, field, rule) {
    if (!data || !field) {
      return;
    }
    let v = data[field];
    if (rule.is_require && !v) {
      data.errors.push(`${rule.name}未填写`);
    }
    if (rule.maxLen && v.length > rule.maxLen) {
      data.errors.push(`${rule.name}长度不允许超过${rule.maxLen}`);
    }
    if (rule.minLen && v.length < rule.minLen) {
      data.errors.push(`${rule.name}长度不允许少于${rule.minLen}`);
    }
    if (rule.eqLen && v.length != rule.eqLen) {
      data.errors.push(`${rule.name}长度为${rule.eqLen}`);
    }
    if (rule.is_number && isNaN(v)) {
      data.errors.push(`${rule.name}需要填写数字类型`);
    }
    if (rule.is_number && isNaN(v)) {
      data.errors.push(`${rule.name}需要填写数字类型`);
    }
  }

}

module.exports = TradeService;