const system = require("../../system");
const ServiceBase = require("../sve.base");
const moment = require("moment");
class EjobService extends ServiceBase {
  constructor() {
    super(ServiceBase.getDaoName(EjobService));
    this.ejobapplySve = system.getObject("service.ejobapplySve");

    this.ecompanyDao = system.getObject("db.ecompanyDao");
    this.ejobtimesDao = system.getObject("db.ejobtimesDao");
    this.ejobcollectDao = system.getObject("db.ejobcollectDao");
    this.ejobapplyDao = system.getObject("db.ejobapplyDao");
    this.ejobrosterDao = system.getObject("db.ejobrosterDao");

    this.ecompanyeventDao = system.getObject("db.ecompanyeventDao");
    this.emessageDao = system.getObject("db.emessageDao");
    this.usereaccountDao = system.getObject("db.usereaccountDao");

  }
  
  async saveJob(ejob) {
    var id = ejob.id;
    var jobTimes = ejob.jobTimes || [];
    ejob.timeType = ejob.timeType || '0';
    ejob.settleType = ejob.settleType || '0';
    ejob.timeSalary = ejob.timeSalary || 0;
    ejob.pieceSalary = ejob.pieceSalary || 0;

    if(id) {
      var job = await this.findById(id);
      if(job.jobStatus != '0') {
        return {msg : '该需求' + job.jobStatusName + ", 不允许修改"};
      }
      job.name = ejob.name;
      job.num = ejob.num;
      job.sex = ejob.sex;
      job.settleType = ejob.settleType;
      job.timeType = ejob.timeType;
      job.timeSalary = ejob.timeSalary;
      job.pieceSalary = ejob.pieceSalary;
      job.addr = ejob.addr;
      job.intro = ejob.intro;
      job.require = ejob.require;
      job.salaryAvg = ejob.salaryAvg;
      await job.save();
      ejob = job;
    } else {
      ejob.limitnum = ejob.num;
      ejob.jobStatus = '0';
      ejob.jobStatusName = '待审核';
      ejob = await this.create(ejob);
      id = ejob.id;
    }

    var delSql = "DELETE FROM `c_ejob_times` WHERE ejob_id = " + id;
    await this.dao.customExecAddOrPutSql(delSql);

    for(var jt of jobTimes) {
      jt.id = 0;
      jt.ecompany_id = ejob.ecompany_id;
      jt.ejob_id = id;
      await this.ejobtimesDao.create(jt);
    }

    this.addSaveJobTip(ejob);
    return {ejob:ejob};
  }

  async addSaveJobTip(ejob) {
    if(!ejob) {
      return;
    }

    var ecompany = await this.ecompanyDao.findById(ejob.ecompany_id);
    var now = moment().format("YYYY-MM-DD HH:mm:ss");
    var content = ecompany.name + "于" + now + "申请发布需求【" + ejob.name + "】";
    var ecompanyEvent = {
      type: 3,
      biz_id: ejob.id,
      content: content,
      status: false,
      ecompany_id: -1,
      user_id: ecompany.user_id,
    };
    this.ecompanyeventDao.create(ecompanyEvent);
    return 1;
  }

  async jobApply(id, userId, usereaccount_id, applyType) {
    applyType = applyType || 0;
    var apply = await this.ejobapplyDao.findOne({
      ejob_id: id,
      user_id: userId
    });
    if (apply) {
      return -1;
    }

    var ejob = await this.findById(id);
    if (!ejob) {
      return -2;
    }

    var apply = {
      ecompany_id: ejob.ecompany_id,
      ejob_id: id,
      user_id: userId,
      usereaccount_id: usereaccount_id,
      econtract_id: 0,
      apply_at: new Date(),
      applyType: applyType,
    }
    apply = await this.ejobapplyDao.create(apply);
    this.addECompanyEvent(apply);
    this.ejobapplySve.addMessage(apply.id, "零工接单", "成功接单");
    return apply.id;
  }

  async autoApply(userId, usereaccount_id, mobile) {
    if (!userId || !usereaccount_id || !mobile) {
      return;
    }

    var rosters = await this.ejobrosterDao.model.findAll({where: {mobile : mobile}});
    if(!rosters || rosters.length == 0) {
      return;
    }

    var r = null;
    var bool = false;
    for(var roster of rosters) {
      if(!roster.ejob_id) {
        continue;
      }
      if(!r) {
        r = roster;
      }
      try {
        var res = await this.jobApply(roster.ejob_id, userId, usereaccount_id, 1);
        if(res > 0) {
          bool = true;
        }
      } catch (error) {
        console.log(error);
      }
    }
    return bool ? r : null;
  }

  async reapply(applyId) {
    var jobapply = await this.ejobapplyDao.findById(applyId);
    if(!jobapply) {
      return -1;
    }
    jobapply.status = '0';
    jobapply.statusName = '待审核';

    await jobapply.save();
    this.addECompanyEvent(jobapply);
    return 1;
  }

  async addECompanyEvent(apply, ejob) {
    if(!apply) {
      return;
    }

    if(!ejob) {
      ejob = await this.findById(apply.ejob_id);
    }
    
    var created_at = moment(ejob.created_at).format("YYYY-MM-DD HH:mm:ss");
    var content = "您" + created_at + "发布的【" + ejob.name + "】已被接单";
    var ecompanyEvent = {
      type: 1,
      biz_id: apply.id,
      content: content,
      status: false,
      ecompany_id: apply.ecompany_id,
      user_id: apply.user_id,
    };
    this.ecompanyeventDao.create(ecompanyEvent);
  }

  async jobInfo(id, userId) {
    var attrs = ["id", "ecompany_id", "name", "num", "limitnum", "sexName", "sex", "settleType", "settleTypeName", "timeType", "timeTypeName",
      "timeSalary", "pieceSalary", "salaryAvg", "addr", "intro", "require", "created_at", "publish_at","reject_at","cancel_at"
    ];
    var job = await this.dao.model.findOne({
      where: {
        id: id
      },
      attrs,
      raw: true
    });
    if (!job) {
      return {};
    }

    var jobs = [job];
    await this.setJobTimes(jobs, "YYYY-MM-DD");
    await this.setCompany(jobs);
    await this.doJobLogic(jobs);
    job.created_at = moment(job.created_at).format("YYYY-MM-DD HH:mm:ss");

    job.isCollect = false;
    job.isApply = false;
    if (userId) {
      var c = await this.ejobcollectDao.findCount({
        where: {
          user_id: userId,
          ejob_id: id
        }
      });
      job.isCollect = !!c;

      var apply = await this.ejobapplyDao.findOne({
        ejob_id: id,
        user_id: userId
      });
      job.isApply = !!apply;
    }
    return job;
  }

  async jobDetail(id, pattern) {
    var timesPattern = pattern.timesPattern || "YYYY-MM-DD";
    var datePattern = pattern.datePattern || "YYYY-MM-DD HH:mm:ss";

    var attrs = ["id", "ecompany_id", "name", "num", "limitnum", "sexName", "sex", "settleType", "settleTypeName", "timeType", "timeTypeName",
      "timeSalary", "pieceSalary", "salaryAvg", "addr", "intro", "require", "created_at", "publish_at","reject_at","cancel_at"
    ];
    var job = await this.dao.model.findOne({
      where: {
        id: id
      },
      attrs,
      raw: true
    });
    if (!job) {
      return {};
    }

    var jobs = [job];
    await this.setJobTimes(jobs, timesPattern);
    await this.setCompany(jobs);
    await this.doJobLogic(jobs);
    this.handleDate(job, ["created_at", "publish_at", "reject_at", "cancel_at"], datePattern);
    return job;
  }

  async jobList(currentPage, pageSize, params) {
    var sort = params.sort || "";
    var orderbyObj = [
      ["created_at", 'desc']
    ];
    var whereObj = {};

    if (params.jobStatus) {
      whereObj.jobStatus = params.jobStatus;
    }

    if (params.settleType) {
      whereObj.settleType = (Number(params.settleType) - 1).toString();
    }

    if (params.sex) {
      if (params.sex == 1) {
        whereObj.sex = 'male';
      } else if (params.sex == 2) {
        whereObj.sex = 'female';
      }
    }

    var salaryMin = Number(params.salaryMin || 0);
    var salaryMax = Number(params.salaryMax || 0);
    if (salaryMin && salaryMax) {
      whereObj.salaryAvg = {
        [this.db.Op.between]: [salaryMin, salaryMax]
      };
    } else if (salaryMin && !salaryMax) {
      whereObj.salaryAvg = {
        [this.db.Op.gte]: salaryMin
      };
    } else if (!salaryMin && salaryMax) {
      whereObj.salaryAvg = {
        [this.db.Op.lte]: salaryMax
      };
    }

    if (params.jobCompanyName && params.jobCompanyName.trim()) {
      // c_epartner
      var ecompanyIds = await this.ecompanyDao.idsLikeName(params.jobCompanyName);
      if (ecompanyIds.length == 0) {
        whereObj.name = {
          [this.db.Op.like]: "%" + params.jobCompanyName + "%"
        };
      } else {
        whereObj[this.db.Op.or] = [{
            ecompany_id: {
              [this.db.Op.in]: ecompanyIds
            }
          },
          {
            name: {
              [this.db.Op.like]: "%" + params.jobCompanyName + "%"
            }
          }
        ];
      }
    }

    var orderbyObj = [
      ["created_at", 'desc']
    ];
    if (params.sort) {
      if (params.sort == 1) {
        orderbyObj = [
          ["salaryAvg", 'desc'],
          ["created_at", 'desc']
        ];
      } else if (params.sort == 2) {
        orderbyObj = [
          ["salaryAvg", 'asc'],
          ["created_at", 'desc']
        ];
      }
    }

    var attributesObj = ["id", "ecompany_id", "name", "num", "limitnum", "sexName", "sex", "settleType", "settleTypeName", "timeType", "timeTypeName",
      "timeSalary", "pieceSalary", "salaryAvg", "addr", "intro", "require", "collectCount", "created_at", "publish_at","reject_at","cancel_at"
    ];
    var page = await this.getPageList(currentPage, pageSize, whereObj, orderbyObj, attributesObj);
    if (page && page.rows) {
      await this.setJobTimes(page.rows);
      await this.setCompany(page.rows);
      await this.doJobLogic(page.rows);
    }
    return page;
  }

  async listByIds(ids, flag) {
    if (!ids || ids.length == 0) {
      return [];
    }
    var jobattrs = "id, ecompany_id, `name`, `num`, limitnum, sexName, sex, settleType, settleTypeName, timeType, timeTypeName, timeSalary, pieceSalary, salaryAvg, addr, intro, `require`, collectCount, created_at, publish_at, reject_at, cancel_at ";
    var sql = "SELECT " + jobattrs + "  FROM c_ejob WHERE id IN (:ids) ";
    var list = await this.customQuery(sql, {
      ids: ids
    });

    if (flag) {
      await this.setJobTimes(list);
      await this.setCompany(list);
      await this.doJobLogic(list);
    }
    return list;
  }

  async findMapByIds(ids, flag) {
    var result = [];
    var list = await this.listByIds(ids, flag);
    if (!list || list.length == 0) {
      return result;
    }


    for (var item of list) {
      result["id_" + item.id] = item;
    }
    return result;
  }

  async collectList(userId, currentPage, pageSize) {
    var whereObj = {
      user_id: userId
    };
    var orderbyObj = [
      ["id", 'desc']
    ];

    var attributesObj = ["id", "ejob_id"];
    var page = await this.ejobcollectDao.getPageList(currentPage, pageSize, whereObj, orderbyObj, attributesObj);
    if (page && page.rows) {
      var jobIds = [];

      for (var row of page.rows) {
        jobIds.push(row.ejob_id);
      }

      if (jobIds.length == 0) {
        return page;
      }

      var jobMap = await this.findMapByIds(jobIds);

      var rows = [];
      for (var row of page.rows) {
        var job = jobMap["id_" + row.ejob_id];
        if (job) {
          rows.push(job);
        }
      }
      page.rows = rows;

      await this.setJobTimes(page.rows);
      await this.setCompany(page.rows);
      await this.doJobLogic(page.rows);
    }
    return page;
  }

  async applyList(params, currentPage, pageSize) {
    var self = this;
    var orderbyObj = [
      ["id", 'desc']
    ];
    var whereObj = {};
    // "0":"待审核","1":"待签约","2":"已签约", "3":"进行中", "4":"已完成", "5":"已撤销", "6":"已驳回", "7":"已失效"
    if (params.user_id) {
      whereObj.user_id = Number(params.user_id);
    }

    var status = (params.status || "").toString();
    if (status) {
      whereObj.status = status;
    }
    var attributesObj = ["id", "ecompany_id", "ejob_id", "econtract_id", "user_id", "status", "statusName", "audit_at",
      "audit_id", "auditRemark", "apply_at", "sign_at", "cancel_at", "created_at"
    ];

    var page = await this.ejobapplyDao.getPageList(currentPage, pageSize, whereObj, orderbyObj, attributesObj);

    if (page && page.rows) {
      var jobIds = [];
      for (var row of page.rows) {
        if (row.ejob_id) {
          jobIds.push(row.ejob_id);
        }
      }

      var jobMap = await this.findMapByIds(jobIds, true);

      for (var row of page.rows) {
        if (row.ejob_id) {
          row.job = jobMap["id_" + row.ejob_id] || {};
        }
        this.handleDate(row, ["created_at", "apply_at", "audit_at", "cancel_at", "sign_at"]);
      }
    }
    return page;
  }

  async jobPage(params) {
    var currentPage = Number(params.currentPage || 0);
    var pageSize = Number(params.pageSize || 10);

    var where = {};

    if(params.ecompanyId) {
      where.ecompany_id = params.ecompanyId;
    }

    var workTimeBegin = params.workTimeBegin;
    var workTimeEnd = params.workTimeEnd;
    if (workTimeBegin || workTimeEnd) {
      var ids = await this.ejobtimesDao.findByTime(companyId, workTimeBegin, workTimeEnd);
      if(!ids || ids.length == 0) {
        return {count:0, rows:[]};
      }
      where.id = {[this.db.Op.in]:ids};
    }

    var num = params.num;
    if (params.num) {
      where.num = params.num;
    }

    if (params.name) {
      where.name = {
        [this.db.Op.like]: "%" + params.name + "%"
      };
    }
    if (params.sex) {
      where.sex = params.sex;
    }

    if (params.settleType) {
      where.settleType = params.settleType;
    }

    if (params.status) {
      where.jobStatus = params.status;
    }

    var name = params.name;
    this.addWhereTime(where, 'created_at', params.applyBegin, params.applyEnd);
    this.addWhereTime(where, 'publish_at', params.publishBegin, params.publishEnd);
    this.addWhereTime(where, 'reject_at', params.rejectBegin, params.rejectEnd);
    this.addWhereTime(where, 'cancel_at', params.cancelBegin, params.cancelEnd);

    var orderby = [
      ["id", 'desc']
    ];
    
    var attributes = ["id", "ecompany_id", "name", "num", "limitnum", "sexName", "sex", "settleType", "settleTypeName", "timeType", "timeTypeName",
      "jobStatus", "jobStatusName",
      "timeSalary", "pieceSalary", "salaryAvg", "addr", "intro", "require", "collectCount", "created_at", "publish_at","reject_at","cancel_at"
    ];
    
    var page = await this.getPageList(currentPage, pageSize, where, orderby, attributes);
    if (page && page.rows) {
      await this.setJobTimes(page.rows);
      await this.setCompany(page.rows); 
      await this.doJobLogic(page.rows);
      for(var row of page.rows) {
        this.handleDate(row, ["created_at", "publish_at", "reject_at", "cancel_at"]);
      }
    }
    return page;
  }

  async doJobLogic(list) {
    if (!list || list.length == 0) {
      return;
    }

    for (var row of list) {
      var salaryArr = [];
      if (row.timeSalary && row.timeSalary > 0 && row.timeType != '0') {
        salaryArr.push(row.timeSalary + row.timeTypeName);
      }

      if (row.pieceSalary && row.pieceSalary > 0) {
        salaryArr.push(row.pieceSalary + "元/件");
      }

      if (salaryArr.length == 0) {
        row.salaryShow = "面议";
      } else {
        row.salaryShow = salaryArr.join(" | ");
      }

      row.workDate = "";
      if (row.jobTimes && row.jobTimes.length > 0) {
        var atNames = [];
        for (var t of row.jobTimes) {
          atNames.push(t.begin_at + "-" + t.end_at);
        }
        row.workDate = atNames.join("、");
      }
    }
  }

  async setCompany(list) {
    if (!list || list.length == 0) {
      return;
    }

    var companyIds = [];
    for (var item of list) {
      companyIds.push(item.ecompany_id || 0);
    }
    var companyMap = await this.ecompanyDao.findMapByIds(companyIds, " id, name, contractMobile ");
    for (var item of list) {
      item.ecompany = companyMap["id_" + (item.ecompany_id || 0)];
    }
  }

  async setJobTimes(list, patten) {
    if (!list || list.length == 0) {
      return;
    }
    var jobIds = [];
    for (var item of list) {
      jobIds.push(item.id);
    }

    var timesMap = await this.ejobtimesDao.findMapByJobIds(jobIds, patten);
    for (var item of list) {
      item.jobTimes = timesMap["ejobId_" + item.id] || [];
    }
  }

  async stat(params) {
    var sql = "SELECT COUNT(1) AS num FROM `c_ejob` WHERE 1 = 1 ";
    if(params.ecompany_id) {
      sql = sql + " AND ecompany_id = :ecompany_id ";
    }
    if(params.begin) {
      sql = sql + " AND created_at >= :begin ";
    }
    if(params.end) {
      sql = sql + " AND created_at <= :end ";
    }
    if(params.jobStatuses) {
      sql = sql + " AND jobStatus IN (:jobStatuses) ";
    }
    var list = await this.customQuery(sql, params);

    if(!list || list.length == 0) {
      return 0;
    }
    return list[0].num || 0;
  }

  async audit(jobId, jobStatus, auditRemark, userId) {
    
    var ejob = await this.findById(jobId);
    if(!ejob) {
      return -1;
    }
    if(ejob.jobStatus != '0') {
      return -2;
    }
    if(jobStatus == '2' && !auditRemark) {
      return -3;
    }
    var created_at = moment(ejob.created_at).format("YYYY-MM-DD HH:mm:ss");
    // 
    var msg = "您" + created_at + "申请的【" + ejob.name + "】需求";
    if(jobStatus == '1') {
      ejob.jobStatus = '1';
      ejob.jobStatusName = "已发布";
      ejob.auditRemark = "";
      msg = msg + "已被发布";
    } else {
      ejob.jobStatus = '2';
      ejob.jobStatusName = "已驳回";
      ejob.auditRemark = auditRemark;
      msg = msg + "已被驳回, 原因【" + auditRemark + "】";
    }
    ejob.audit_at = new Date();
    ejob.audit_id = userId;
    await ejob.save();

    this.emessageDao.create({
      user_id : 0,
      type : 4,
      title : jobStatus == '1' ? "审核通过" : "审核驳回",
      read : 0,
      content : msg
    });
    this.ecompanyeventDao.doBiz(ejob.id, 3);
    return 1;
  }
}

module.exports = EjobService;