const system = require("../../../system");
const ServiceBase = require("../../sve.base");
const settings = require("../../../../config/settings");
const moment = require("moment");
// const pushTx = require("../../../utils/totxClient")
const pushQft = require("../../../utils/toqifutongClient")


class DeliverService extends ServiceBase {
  constructor() {
    super("delivery", ServiceBase.getDaoName(DeliverService));
    this.cacheinfoDao = system.getObject("db.delivery.cacheinfoDao");
    this.materialDao = system.getObject("db.delivery.materialDao");
    this.statuslogDao = system.getObject("db.bizchance.statuslogDao");
    this.qualificationDao = system.getObject("db.delivery.qualificationDao");
    this.annualreportDao = system.getObject("db.delivery.annualreportDao");
  }

  async temporarySave(pobj) {
    const deliverData = await this.dao.findOne({
      id: pobj.deliver_id
    });
    if (!deliverData) {
      throw new Error("没有关联的交付单");
    }
    let result = await this.cacheinfoDao.createOrUpdate(pobj);
    return result;
  }

  async findTemporary(pobj) {
    return this.cacheinfoDao.findOne({
      deliver_id: pobj.deliver_id
    });
  }

  async updateRemarkByDeliverCode(qobj) {
    var self = this;
    var setobj={remark:qobj.remark}
    var whereobj = { "delivery_code": qobj.deliverNumber };
    return self.db.transaction(async function (t) {
        return await self.dao.updateByWhere(setobj,whereobj,t);
    });
}

  async submitMaterials(pobj) {
    /**
     * 1.此状态下是否可以提交材料
     * 2.推送到腾讯
     * 2.同步暂存数据表
     * 3.存储到材料表
     * 4.更改 交付单流转状态
     */
    const deliverData = await this.dao.findOne({
      id: pobj.deliver_id
    });
    if (!deliverData) {
      throw new Error("查不到此交付单");
    }

    if ([system.SERVERSESTATUS.COLLECTING, system.SERVERSESTATUS.USERCONFIRMATIONREJECT].includes(deliverData.delivery_status)) {
      await pushQft.submitMaterials(deliverData, JSON.parse(JSON.stringify(pobj.cache_info)))
    }

    return this.db.transaction(async (t) => {
      await this.cacheinfoDao.createOrUpdate(pobj, t);
      await this.materialDao.createOrUpdate(pobj, t);
      if (deliverData.source_number === "aliCloud") {
        if ([system.SERVERSESTATUS.COLLECTING, system.SERVERSESTATUS.USERCONFIRMATIONREJECT].includes(deliverData.delivery_status)) {
          await this.dao.updateByWhere({
            delivery_status: system.SERVERSESTATUS.USERCONFIRMATIONWAIT
          }, {
            id: pobj.deliver_id
          }, t);
          this.statuslogDao.create({
            flow_type: system.FLOWCODE.DELIVERY,
            flow_id: pobj.deliver_id,
            status_code: system.SERVERSESTATUS.USERCONFIRMATIONWAIT,
            salesman_id: pobj.userid,
            salesman_name: pobj.username
          });
        }
      }

      // 更新公司名称
      if (pobj && pobj.cache_info && pobj.cache_info.proposerFormInfo && pobj.cache_info.proposerFormInfo.businessLicense && pobj.cache_info.proposerFormInfo.businessLicense.name) {
        await this.deliveryDao.updateByWhere({
          company_name: pobj.cache_info.proposerFormInfo.businessLicense.name,
          delivery_info: {
            ...deliverData.delivery_info,
            companyName: pobj.cache_info.proposerFormInfo.businessLicense.name
          }
        }, {
          delivery_code: deliverData.delivery_code
        }, t);
      }
      return "SUCCESS"
    });
  }

  async findInfo(pobj) {
    /**
     * 交付单表 关联  材料表(材料基本信息、邮寄信息) 、 资质信息表
     */
    let result = await this.dao.findInfo(pobj);
    if (!result) {
      throw new Error("交付单不可查看");
    }
    result = JSON.parse(JSON.stringify(result));
    if (result.master_source_number) {
      let annualReportData = await this.dao.findOne({
        master_source_number: result.master_source_number,
        id: {
          $ne: result.id
        }
      });
      if (annualReportData) {
        result.delivery_info.annualReport = true;
      } else {
        result.delivery_info.annualReport = false;
      }
    }
    return result;
  }

  async changeDeliveryStatus(pobj) {
    /**
     * 判断 交付单状态下能否更新
     */
    const deliverData = await this.dao.findOne({
      id: pobj.id
    });
    if (!deliverData) {
      throw new Error("没有此交付单");
    }
    // if (![system.SERVERSESTATUS.SUBMITING, system.SERVERSESTATUS.POSTING].includes(deliverData.delivery_status)) {
    //     throw new Error("此状态下不可手动更新办理状态");
    // }
    let status;
    // let txstatus;
    switch (deliverData.delivery_status) {
      case system.SERVERSESTATUS.USERCONFIRMATIONRESOLVE:
        status = system.SERVERSESTATUS.ACCOUNTREGISTRATION;
        await pushQft.changeStatus(deliverData, pushQft.ALISTATUS.ACCOUNTREGISTRATION);
        break
      case system.SERVERSESTATUS.ACCOUNTREGISTRATION:
        status = system.SERVERSESTATUS.SUBMITING;
        await pushQft.changeStatus(deliverData, pushQft.ALISTATUS.SUBMITING);
        break
      case system.SERVERSESTATUS.DISPOSEING:
        // 查询 资质信息 
        const qualificationData = await this.qualificationDao.findOne({
          deliver_id: deliverData.id
        });
        if (!qualificationData) {
          throw new Error("请上传办理的资质证照信息");
        }
        status = system.SERVERSESTATUS.THROUGH;

        await pushQft.changeStatus(deliverData, pushQft.ALISTATUS.THROUGH, {
          officialFileURL: qualificationData.file.url,
          certificateNumber: qualificationData.certificateNumber,
          certificateStartTime: moment(qualificationData.startAt).format('YYYY-MM-DD'),
          certificateEndTime: moment(qualificationData.endAt).subtract(1, 'days').format('YYYY-MM-DD')
        });

        break
      case system.SERVERSESTATUS.THROUGH:
        status = system.SERVERSESTATUS.SUCCESS;
        break

      case system.SERVERSESTATUS.SUBMITING:
        status = system.SERVERSESTATUS.DISPOSEING;
        // txstatus = pushTx.TXSTATUS.DISPOSEING;
        await pushQft.changeStatus(deliverData, pushQft.ALISTATUS.DISPOSEING);

        break
      case system.SERVERSESTATUS.POSTING:
        status = system.SERVERSESTATUS.SUCCESS;
        // txstatus = pushTx.TXSTATUS.SUCCESS;
        break
      default:
        throw new Error("此状态手动不能更改");
    }

    // await pushTx.pushChangeOrder(txstatus, deliverData.delivery_code);

    await this.dao.updateByWhere({
      delivery_status: status
    }, {
      id: pobj.id
    })
    this.statuslogDao.create({
      flow_type: system.FLOWCODE.DELIVERY,
      flow_id: pobj.id,
      status_code: status,
      salesman_id: pobj.userid,
      salesman_name: pobj.username
    });
    return "success"
  }

  /**
       *  阿里渠道
       * 1. 交付单起始状态 为 已接单
       * 2. 点击详情 更新为 用户待上传材料
       * 3. 当用户上传完材料 自动更新为 收集材料中
       * 
       *  其他渠道 
       * 1. 交付单起始状态 为 已接单
       * 2. 点击详情 更新为 收集材料中
  */
  async toCollecting(pobj) {
    const deliverData = await this.dao.findOne({
      id: pobj.id
    });
    if (!deliverData) {
      throw new Error("没有此交付单");
    }

    if (system.SERVERSESTATUS.RECEIVED === deliverData.delivery_status) {
      let status;
      if (deliverData.source_number === "aliCloud") {
        status = system.SERVERSESTATUS.USERUPLOADWAIT
      } else {
        status = system.SERVERSESTATUS.COLLECTING
      }
      await this.dao.updateByWhere({
        delivery_status: status
      }, {
        id: pobj.id
      });
      this.statuslogDao.create({
        flow_type: system.FLOWCODE.DELIVERY,
        flow_id: pobj.id,
        status_code: status,
        salesman_id: pobj.userid,
        salesman_name: pobj.username
      });
    }

    return "SUCCESS"
  }

  /**
   * 易名 渠道 专用
   * 记录 上传步骤 
   * @param {*} pobj 
   */
  async toUpload(pobj) {
    const deliverData = await this.dao.findOne({
      id: pobj.id
    });
    if (!deliverData) {
      throw new Error("没有此交付单");
    }
    if (system.SERVERSESTATUS.COLLECTING === deliverData.delivery_status && deliverData.source_number === "ename") {
      await pushQft.changeStatus(deliverData, 505);
      let status;
      status = system.SERVERSESTATUS.FILLING
      await this.dao.updateByWhere({
        delivery_status: status
      }, {
        id: pobj.id
      });
      this.statuslogDao.create({
        flow_type: system.FLOWCODE.DELIVERY,
        flow_id: pobj.id,
        status_code: status,
        salesman_id: pobj.userid,
        salesman_name: pobj.username
      });
    }

    return "SUCCESS"
  }


  /**
      * 1. 保存资质信息
  */
  async addQualification(pobj) {

    const deliverData = await this.dao.findOne({
      id: pobj.deliver_id
    });
    if (!deliverData) {
      throw new Error("查不到交付单");
    }
    await this.qualificationDao.createOrUpdate(pobj);
    return "SUCCESS"
  }

  async closeDeliver(pobj) {
    /**
     * 1 关闭资质
     * 2 查询是否有年报信息 关闭
     */
    const deliverData = await this.dao.findOne({
      id: pobj.id
    });
    if (!deliverData) {
      throw new Error("查不到交付单");
    }
    // if (![system.SERVERSESTATUS.RECEIVED, system.SERVERSESTATUS.COLLECTING].includes(deliverData.delivery_status)) {
    //     throw new Error("该交付单状态下不可提交");
    // }
    // 推送 关闭交付
    // await pushTx.pushChangeOrder(pushTx.TXSTATUS.CLOSED, deliverData.delivery_code, {
    //     close_reason: pobj.close_reason
    // });
    // 推送 退费
    // await pushTx.returnPremium(deliverData.delivery_code);
    await pushQft.enamecloseDelivery(deliverData, {
      note: pobj.close_reason
    })
    // 年报逻辑
    // let annualReportData;
    // if (deliverData.master_source_number) {
    //     annualReportData = await this.dao.findOne({
    //         master_source_number: deliverData.master_source_number,
    //         id: {
    //             $ne: deliverData.id
    //         }
    //     });
    //     // 推送 关闭交付 资质
    //     if (annualReportData) {
    //         // await pushTx.pushChangeOrder(pushTx.TXSTATUS.CLOSED, annualReportData.delivery_code, {
    //         //     close_reason: "对应的资质交付关闭了"
    //         // });
    //         // 推送 年报退费
    //         // await pushTx.returnPremium(annualReportData.delivery_code);
    //     }
    // }
    return this.db.transaction(async (t) => {
      await this.dao.updateByWhere({
        delivery_status: system.SERVERSESTATUS.CLOSED,
        close_reason: pobj.close_reason
      }, {
        id: pobj.id
      }, t);
      this.statuslogDao.create({
        flow_type: system.FLOWCODE.DELIVERY,
        flow_id: pobj.id,
        status_code: system.SERVERSESTATUS.CLOSED,
        salesman_id: pobj.userid,
        salesman_name: pobj.username
      });
      // if (annualReportData) {
      //     await this.dao.updateByWhere({
      //         delivery_status: system.SERVERSESTATUS.CLOSED,
      //         close_reason: "对应的资质交付关闭了"
      //     }, {
      //         id: annualReportData.id
      //     }, t);
      //     this.statuslogDao.create({
      //         flow_type: system.FLOWCODE.DELIVERY,
      //         flow_id: annualReportData.id,
      //         status_code: system.SERVERSESTATUS.CLOSED,
      //         salesman_id: pobj.userid,
      //         salesman_name: pobj.username
      //     });
      // }
      return "success"
    });

  }

  async addMail(pobj) {
    /**
     * 判断状态
     * 保存 邮寄信息
     * 更改流转状态
     */
    let result = await this.dao.findInfo(pobj);
    if (!result) {
      throw new Error("交付单不可查看");
    }

    if (result.source_number === "tencentCloud") {
      if (!result.qualification) {
        throw new Error("请先上传资质信息");
      }
      if (result.delivery_status !== system.SERVERSESTATUS.DISPOSEING) {
        throw new Error("该状态下不可填写邮寄信息");
      }
    }


    const { material } = result;
    let { proposerInfo } = material
    proposerInfo.recipientInfo = pobj.recipientInfo;


    // await pushTx.pushChangeOrder(pushTx.TXSTATUS.POSTING, result.delivery_code, {
    //     qualification: result.qualification,
    //     recipientInfo: pobj.recipientInfo
    // });


    return this.db.transaction(async (t) => {
      await this.materialDao.updateByWhere({
        proposerInfo
      }, {
        id: material.id
      }, t);

      if (result.source_number === "tencentCloud") {
        await this.dao.updateByWhere({
          delivery_status: system.SERVERSESTATUS.POSTING,
        }, {
          id: pobj.id
        }, t);

        this.statuslogDao.create({
          flow_type: system.FLOWCODE.DELIVERY,
          flow_id: pobj.id,
          status_code: system.SERVERSESTATUS.POSTING,
          salesman_id: pobj.userid,
          salesman_name: pobj.username
        });
      }
      return "success"
    });
  }

  async findAnnualReportInfo(pobj) {
    let annualReportResult = await this.dao.findAnnualReportInfo(pobj);
    if (!annualReportResult) {
      throw new Error("交付单不可查看");
    }
    if (!annualReportResult.master_source_number) {
      throw new Error("查不到主订单号");
    }
    let data = await this.dao.findOne({
      master_source_number: annualReportResult.master_source_number,
      id: {
        $ne: annualReportResult.id
      }
    });
    if (!data) {
      throw new Error("查不到对应的交付单");
    }
    let result = await this.dao.findInfo({ ...pobj, id: data.id });
    annualReportResult = JSON.parse(JSON.stringify(annualReportResult));
    const { material: { proposerInfo: { businessLicense } }, qualification } = result;
    annualReportResult.businessLicense = businessLicense;
    annualReportResult.qualification = qualification;
    return annualReportResult;
  }

  async declareReport(pobj) {
    /**
     * 1. 更新 年报信息
     * 2. 判断是否 都已申报完毕
     * 3. 改变 交付单状态
     */
    const annualReportData = await this.annualreportDao.findOne({
      id: pobj.id
    });
    if (!annualReportData) {
      throw new Error("查不到此年报信息");
    }

    const deliverData = await this.dao.findOne({
      id: annualReportData.deliver_id
    });
    // 年报逻辑
    let isChange = false;
    if (deliverData && deliverData.delivery_status === system.ANNUALREPORT.TAKEEFFECT) {
      const annualReports = await this.annualreportDao.findAll({
        deliver_id: deliverData.id,
        status: system.ANNUALREPORT.WAITDECLARE
      });
      const ids = annualReports.map(item => {
        return item.id;
      });
      if (ids.length === 1 && ids.includes(annualReportData.id)) {
        isChange = true
      }
    }

    // 推送年报信息 
    // await pushTx.pushDeclareReport({ id: pobj.id, file: pobj.file }, deliverData);
    //修改年报订单状态
    // if (isChange) {
    //     await pushTx.pushChangeOrder(pushTx.TXSTATUS.SUCCESS, deliverData.delivery_code);
    // }

    return this.db.transaction(async (t) => {
      await this.annualreportDao.updateByWhere({
        file: pobj.file,
        status: system.ANNUALREPORT.DECLARESUCCESS
      }, {
        id: annualReportData.id
      }, t);
      if (isChange) {
        await this.dao.updateByWhere({
          delivery_status: system.ANNUALREPORT.SUCCESS
        }, {
          id: deliverData.id
        }, t);
        this.statuslogDao.create({
          flow_type: system.FLOWCODE.DELIVERY,
          flow_id: deliverData.id,
          status_code: system.ANNUALREPORT.SUCCESS,
          salesman_id: pobj.userid,
          salesman_name: pobj.username
        });
      }
      return 'success';
    });
  }

  async findRelationOrder(pobj) {
    const deliverData = await this.dao.findOne({
      id: pobj.id
    });
    if (!deliverData) {
      throw new Error("没有此交付单");
    }
    if (!deliverData.master_source_number) {
      return []
    }
    let result = [];
    const deliverDatas = await this.dao.findAll({
      master_source_number: deliverData.master_source_number
    });
    if (deliverDatas && deliverDatas.length > 0) {
      result = deliverDatas.map(item => {
        return item.delivery_code;
      }).filter(item => {
        return item !== deliverData.delivery_code;
      });
    }
    return result;
  }


  async changeSalesman(pobj) {
    const { orderNumber, userId, userName, salesman_opcode } = pobj
    await this.dao.updateByWhere({
      salesman_opcode: salesman_opcode,
      salesman_name: userName
    }, {
      scheme_number: orderNumber
    });
    return "SUCCESS"
  }
}
module.exports = DeliverService;
