var system = require("../../../system")
const CtlBase = require("../../ctlms.base");
const validation = system.getObject("util.validation");
var moment = require('moment');
const settings = require("../../../../config/settings");
const axios = require("axios");
class InvoiceCtl extends CtlBase {
  constructor() {
    super();
    this.saasinvoiceSve = system.getObject("service.saas.saasinvoiceSve");
    this.orderSve = system.getObject("service.saas.orderSve");
    this.tradeSve = system.getObject("service.trade.tradeSve");
    this.redisClient = system.getObject("util.redisClient");
  }

  // 审核
  async audit(params, pobj2, req) {
    try {
      params.id = this.trim(params.id);
      if (!params.id) {
        return system.getResult(null, "发票申请不存在");
      }
      params.remark = this.trim(params.remark);
      if (!params.remark) {
        return system.getResult(null, "请填写审核备注");
      }
      params.status = Number(params.status || 0) ? "1010" : "1020";
      let rs = await this.saasinvoiceSve.audit(params)
      if (rs.status === 0 && !params.status) {
        await this.tradeSve.cancelInvoice({saas_invoice_id: params.id});
      }
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  // 发票开具
  // 审核
  async makeout(params, pobj2, req) {
    try {
      validation.check(params, 'invoice_no', {name: "发票代码", is_require: true});
      validation.check(params, 'invoice_number', {name: "发票号码", is_require: true});
      validation.check(params, 'invoice_time', {name: "开票时间", is_require: true});
      validation.check(params, 'mail_no', {name: "快递单号", is_require: true});
      validation.check(params, 'invoice_img', {name: "发票图片", is_require: true});
      let rs = await this.saasinvoiceSve.makeout(params);
      return rs;
    } catch (error) {
      let msg = error.message;
      if (msg.startsWith("bpo-validation-error:")) {
        return system.getResult(null, msg.replace("bpo-validation-error:", ""));
      }
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  async platformTitleAddr(params, pobj2, req) {
    try {
      let id = params.id;
      let apply = await this.saasinvoiceSve.invoiceapplyById(params);
      if (!apply.data || !apply.data.id) {
        return system.getResult(null, "发票申请不存在");
      }
      apply = apply.data;
      let result = {};
      result.title = {
        "merchant_name": apply.from_name,
        "merchant_credit_code": apply.from_credit_code,
        "merchant_addr": apply.from_addr,
        "merchant_mobile": apply.from_mobile,
        "merchant_bank": apply.from_bank,
        "merchant_account": apply.from_account
      };
      result.addr = {"mail_addr": "", "mail_mobile": "", "mail_to": ""};
      return system.getResultSuccess(result);
    } catch (error) {
      let msg = error.message;
      if (msg.startsWith("bpo-validation-error:")) {
        return system.getResult(null, msg.replace("bpo-validation-error:", ""));
      }
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  async platformInvoiceInfo(params, pobj2, req) {
    try {
      let id = params.id;
      let invoice_type = params.invoice_type;
      let apply = await this.saasinvoiceSve.invoiceapplyById(params);
      if (!apply.data || !apply.data.id) {
        return system.getResult(null, "发票申请不存在");
      }
      // apply = apply.data;

      let result = await this.buildTradeInvoice(params);
      return result;
    } catch (error) {
      let msg = error.message;
      if (msg.startsWith("bpo-validation-error:")) {
        return system.getResult(null, msg.replace("bpo-validation-error:", ""));
      }
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  async buildTradeInvoice(params) {
    let invoiceId = params.id;
    let invoice_type = params.invoice_type;
    // 查交易
    let items = await this.tradeSve.itemByInvoiceId({saas_invoice_id: invoiceId});
    items = items.data;
    if (!items || items.length == 0) {
      return system.getResult(null, "该发票缺少交易信息，请联系平台查看原因");
    }
    let bmMap = {};
    let creditCodes = [];
    for (let item of items) {
      let creditCode = item.credit_code;
      let list = bmMap[creditCode] || [];
      list.push(item);
      bmMap[creditCode] = list;
      creditCodes.push(creditCode);
    }
    let businessmenMap = await this.orderSve.mapByCreditCodes({creditCodes: creditCodes});
    businessmenMap = businessmenMap.data;

    let invoiceList = [];
    let calcParams = [];

    for (let creditCode in bmMap) {
      let businessmen = businessmenMap[creditCode];
      let itemList = bmMap[creditCode];
      let amount = 0;
      for (let item of itemList) {
        amount = amount + Number(item.amt || 0);
      }
      calcParams.push({
        "credit_code": creditCode,
        "invoiced_time": moment().format("YYYY-MM-DD hh:mm:ss"),
        "invoice_type": invoice_type,
        "invoice_amount": amount
      });

      // TODO 总统计算 end
      invoiceList.push({
        "name": businessmen.name,
        "credit_code": creditCode,
        "is_bank": businessmen.isBank,
        "invoice_amount": amount,
        "personal_invoice_tax": 0,
        "additional_tax": 0,
        "service_tax": 0,
        "value_added_tax": 0,
        "unit": "",
        "quantity": "",
        "price": "",
        "remark": ""
      });
    }

    let additional_tax_total = 0;
    let personal_invoice_tax_total = 0;
    let value_added_tax_total = 0;
    let service_tax_total = 0;

    // TODO 总统计算 begin
    // 计算税金
    try {
      let url = settings.deliverSysApi().calcInvoice;
      let res = await axios({
        method: 'post',
        url: url,
        data: calcParams
      });
      if(!res || !res.data || res.data.status !=0 || res.data.data.length==0){
        return system.getResult(null,`试算错误`);
      }

      let calcList = res.data.data;
      let calcMap = {};
      for (let c of calcList) {
        calcMap[c.credit_code] = c;
      }

      for (let invoice of invoiceList) {
        let invoiceCalc = calcMap[invoice.credit_code];
        additional_tax_total = additional_tax_total + Number(invoiceCalc.additional_tax);
        personal_invoice_tax_total = personal_invoice_tax_total + Number(invoiceCalc.personal_invoice_tax);
        value_added_tax_total = value_added_tax_total + Number(invoiceCalc.value_added_tax);
        service_tax_total = service_tax_total + Number(invoiceCalc.service_tax);

        invoice.personal_invoice_tax = Number(invoiceCalc.personal_invoice_tax);
        invoice.additional_tax = Number(invoiceCalc.additional_tax);
        invoice.service_tax = Number(invoiceCalc.service_tax);
        invoice.value_added_tax = Number(invoiceCalc.value_added_tax);
      }

      return system.getResultSuccess({
        tax: {
          additional_tax_total: additional_tax_total,
          personal_invoice_tax_total: personal_invoice_tax_total,
          value_added_tax_total: value_added_tax_total,
          service_tax_total: service_tax_total,
        },
        invoiceList: invoiceList
      });
    } catch (error) {
      console.log(error);
      return system.getResult(null,`系统错误`);
    }
  }

  async platformInvoiceApply(params, pobj2, req) {
    try {

      validation.check(params, "id", {name: "发票申请信息", is_require: true});
      validation.check(params, "invoice_type", {name: "发票类型", dics: ['00', "10", "20"]});
      validation.check(params, "invoiceList", {name: "开票信息", arr_require: true});
      validation.check(params, "mail_to", {name: "收件人", arr_require: true});
      validation.check(params, "mail_mobile", {name: "联系电话", arr_require: true});
      validation.check(params, "mail_addr", {name: "邮寄地址", arr_require: true});

      let invoiceList = params.invoiceList;
      let apply = await this.saasinvoiceSve.invoiceapplyById({id: params.id});
      if (!apply.data || !apply.data.id) {
        return system.getResult(null, "发票申请不存在");
      }
      apply = apply.data;
      if (apply.status != 1040) {
        return system.getResult(null, "已提交平台申请，请勿重复提交");
      }

      let creditCodes = [];
      for (let invoice of invoiceList) {
        creditCodes.push(invoice.credit_code);
      }
      let businessmenMap = await this.orderSve.mapByCreditCodes({creditCodes: creditCodes});
      businessmenMap = businessmenMap.data;

      for (let invoice of invoiceList) {
        validation.check(businessmenMap, invoice.credit_code, {name: `个体户[${invoice.credit_code}]`, is_require: true});
      }

      let applyList = [];
      let batch_no = await this.redisClient.genrateId("invoice_batch_no");
      for (let invoice of invoiceList) {
        let bussinessmen = businessmenMap[invoice.credit_code];
        let apply_no = await this.redisClient.genrateId("invoice_apply_no");
        let data = {
          saas_id: apply.saas_id,
          saas_merchant_id: apply.saas_merchant_id,
          parent_id: apply.id,
          owner_type: "10",
          status: "1000",
          batch_no: batch_no,
          apply_no: apply_no,
          fee_type: "10",
          invoice_type: this.trim(params.invoice_type),

          from_name: bussinessmen.name,
          from_credit_code: bussinessmen.credit_code,
          from_mobile: bussinessmen.legal_mobile,
          from_addr: bussinessmen.business_place,
          from_bank: bussinessmen.bank_name,
          from_account: bussinessmen.bank_no,

          to_name: this.trim(apply.from_name),
          to_credit_code: this.trim(apply.from_credit_code),
          to_mobile: this.trim(apply.from_mobile),
          to_addr: this.trim(apply.from_addr),
          to_bank: this.trim(apply.from_bank),
          to_account: this.trim(apply.from_account),

          mail_addr: this.trim(params.mail_addr),
          mail_mobile: this.trim(params.mail_mobile),
          mail_to: this.trim(params.mail_to),
        };

        applyList.push(data);
      }
      let rs = await this.saasinvoiceSve.applyBulkSave({
        fee_type: apply.fee_type,
        dataList: applyList,
        parent_id: apply.id,
        updateStatus: {
          id: apply.id,
          preStatus: "1040",
          status: "1060",
        }
      });
      return system.getResultSuccess(rs);
    } catch (error) {
      let msg = error.message;
      if (msg.startsWith("bpo-validation-error:")) {
        return system.getResult(null, msg.replace("bpo-validation-error:", ""));
      }
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  //发票列表
  async invoicePage(params, pobj2, req) {
    try {
      let rs = await this.saasinvoiceSve.platforminvoicePage(params);
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  //发票申请列表
  async applyPage(params, pobj2, req) {
    try {
      params.owner_type = "00";
      let rs = await this.saasinvoiceSve.platforminvoiceapplyPage(params);
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  //发票申请列表
  async platformApplyPage(params, pobj2, req) {
    try {
      params.owner_type = "10";
      let rs = await this.saasinvoiceSve.platforminvoiceapplyPage(params);
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  // 审核
  async platformAudit(params, pobj2, req) {
    try {
      params.id = this.trim(params.id);
      if (!params.id) {
        return system.getResult(null, "发票申请不存在");
      }
      params.remark = this.trim(params.remark);
      if (!params.remark) {
        return system.getResult(null, "请填写审核备注");
      }
      params.status = Number(params.status || 0) ? "1010" : "1020";
      let rs = await this.saasinvoiceSve.audit(params)
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }

  // 审核
  async platformHandle(params, pobj2, req) {
    try {
      params.id = this.trim(params.id);
      if (!params.id) {
        return system.getResult(null, "发票申请不存在");
      }
      let rs = await this.saasinvoiceSve.platformHandle(params)
      return rs;
    } catch (error) {
      return system.getResult(null, `系统错误 错误信息 ${error}`);
    }
  }


}

module.exports = InvoiceCtl;
