package cn.estsh.i3plus.ext.mes.apiservice.schedulejob;

import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.mes.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.apiservice.util.DateUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.impp.framework.base.schedule.BaseImppScheduleJob;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.init.ApplicationProperties;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.ApiOperation;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xiangming.liao
 * @version 1.0
 * @date 2021/2/2 16:44
 **/
@DisallowConcurrentExecution
@ApiOperation("工程巡回确认的点检单创建定时任务")
public class ProjectTourConfirmCreate extends BaseImppScheduleJob {

    @Autowired
    private MesOrderRuleRepository mesOrderRuleRDao;
    @Autowired
    private MesOrderJobRepository mesOrderJobRDao;
    @Autowired
    private ISyncFuncService syncFuncService;
    @Autowired
    private MesProjectConfirmRepository mesProjectConfirmRDao;
    @Autowired
    private MesProjectTourDetailRepository projectTourDetailRDao;
    @Autowired
    private MesWorkOrderExtRepository mesWorkOrderExtRDao;
    @Autowired
    private MesWorkCenterExtRepository workCenterRDao;


    public ProjectTourConfirmCreate() {
        super(ProjectTourConfirmCreate.class, "工程巡回确认的点检单创建定时任务");
    }

    @Override
    public void executeImppJob(JobExecutionContext context, ApplicationProperties applicationProperties) {
        try {
            String jobParam = this.getJobParam();
            JSONObject jsonObject = JSONObject.parseObject(jobParam);
            String organizationCode = jsonObject.get("organizationCode").toString();
            List<MesOrderRule> rules = findRule(organizationCode);
            if (!CollectionUtils.isEmpty(rules)) {
                for (MesOrderRule rule : rules) {
                    String produceTime = rule.getProduceTime();
                    String workCenterCode = rule.getWorkCenterCode();

                    //当前时间是否达到产生点检时间
                    boolean isPunctual = belongCalendar(produceTime);
                    if (isPunctual) {
                        List<MesOrderJob> orderJobs = findOrderJob(organizationCode, workCenterCode);
                        if (!CollectionUtils.isEmpty(orderJobs)) {

                            boolean isNeedGenerate = true;
                            for (MesOrderJob orderJob : orderJobs) {
                                String generateTime = orderJob.getGenerateTime();
                                if (haveJob(produceTime, generateTime)) {
                                    isNeedGenerate = false;
                                    break;
                                }

                            }
                            List<MesWorkOrderExt> workOrders = findWorkOrder(organizationCode, workCenterCode);
                            if (!CollectionUtils.isEmpty(workOrders) && isNeedGenerate) {
                                generateOrderJob(organizationCode, workCenterCode, produceTime);
                            }

                        } else {
                            LOGGER.info("生产线{}时间{}生成了工程巡回确认点检单", workCenterCode, produceTime);
                            generateOrderJob(organizationCode, workCenterCode, produceTime);
                        }
                    }
                }
            }

        } catch (Exception e) {
            LOGGER.error("工程巡回确认的点检定时任务参数异常");
            LOGGER.error(Arrays.toString(e.getStackTrace()));
        }
    }

    private MesWorkCenterExt getWorkCenter(String workCenterCode, String organizeCode) {
        return workCenterRDao.getByProperty(
                new String[]{MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED},
                new Object[]{workCenterCode, organizeCode,
                        CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.IS_DEAL.NO.getValue()});
    }

    private void generateOrderJob(String organizeCode, String workCenterCode, String produceTime) {
        List<MesProjectConfirm> projectConfirmList = findProjectConfirm(organizeCode);
        if(!CollectionUtils.isEmpty(projectConfirmList)){
            MesWorkCenterExt workCenter = getWorkCenter(workCenterCode, organizeCode);
            MesOrderJob newOrderJob = new MesOrderJob();
            newOrderJob.setTaskType(MesExtEnumUtil.MES_OR_TASK_TYPE.PROCESS_TASK.getValue());
            newOrderJob.setOrderType(MesExtEnumUtil.MES_OR_ORDER_TYPE.PROJECT_TOUR_CONTRIM.getValue());
            newOrderJob.setOrderNo(getOrderNo(organizeCode));
            newOrderJob.setWorkCenterCode(workCenterCode);
            newOrderJob.setOrderStatus(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
            newOrderJob.setOrderDate(TimeTool.getToday());
            newOrderJob.setWorkTime(TimeTool.getToday());
            newOrderJob.setGenerateTime(DateUtil.formatDate(MesExtConstWords.DATE_FORMAT, new Date()) + " " + produceTime);
            newOrderJob.setOrganizeCode(organizeCode);
            newOrderJob.setIsValid(MesExtEnumUtil.IS_VAILD.VAILD.getValue());
            newOrderJob.setIsDeleted(MesEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
            newOrderJob.setCreateDatetime(DateUtil.formatDate());
            newOrderJob.setModifyDatetime(DateUtil.formatDate());
            newOrderJob.setShiftCode(workCenter.getShiftCode());
            MesOrderJob job = mesOrderJobRDao.save(newOrderJob);

            for (MesProjectConfirm mesProjectConfirm : projectConfirmList) {
                MesProjectTourDetail mesProjectTourDetail = new MesProjectTourDetail();
                mesProjectTourDetail.setWorkCenterCode(job.getWorkCenterCode());
                mesProjectTourDetail.setShiftCode(job.getShiftCode());
                mesProjectTourDetail.setShiftGroupCheck(MesExtEnumUtil.SHIFT_GROUP_CHECK.NO.getValue());
                mesProjectTourDetail.setQualityCheck(MesExtEnumUtil.QUALITY_CHECK.NO.getValue());
                mesProjectTourDetail.setOrderNo(job.getOrderNo());
                mesProjectTourDetail.setOrderDate(job.getOrderDate());
                BeanUtils.copyProperties(mesProjectConfirm, mesProjectTourDetail, MesExtConstWords.ID);
                mesProjectTourDetail.setOrganizeCode(organizeCode);
                mesProjectTourDetail.setIsValid(MesExtEnumUtil.IS_VAILD.VAILD.getValue());
                mesProjectTourDetail.setIsDeleted(MesEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
                mesProjectTourDetail.setCreateDatetime(DateUtil.formatDate());
                mesProjectTourDetail.setModifyDatetime(DateUtil.formatDate());
                projectTourDetailRDao.save(mesProjectTourDetail);
            }
        }
    }

    public List<MesOrderRule> findRule(String organizeCode){
        int taskType = MesExtEnumUtil.MES_OR_TASK_TYPE.PROCESS_TASK.getValue();
        int orderType = MesExtEnumUtil.MES_OR_ORDER_TYPE.PROJECT_TOUR_CONTRIM.getValue();
        int createRule = MesExtEnumUtil.MES_OR_CREATE_RULE.TIME_TO_CREATE.getValue();
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(taskType,MesExtConstWords.TASK_TYPE,ddlPackBean);
        DdlPreparedPack.getNumEqualPack(orderType,MesExtConstWords.ORDER_TYPE,ddlPackBean);
        DdlPreparedPack.getNumEqualPack(createRule,MesExtConstWords.CREATE_RULE,ddlPackBean);
        return mesOrderRuleRDao.findByHqlWhere(ddlPackBean);


    }

    /**
     * @return boolean
     * @Description: 判断当前时间是否是产生时间
     * @Param [produceTime]
     * @Date 2021/3/25 9:50
     **/
    private boolean belongCalendar(String produceTime) {
        Date nowTime = TimeTool.parseDate(TimeTool.getNowTime("yyyy-MM-dd HH:mm"));
        Date beginTime = TimeTool.parseDate(TimeTool.getToday() + MesExtConstWords.ONE_SPACE + produceTime);
        //对时间进行加1分钟
        Date endTime = DateUtil.addTime(beginTime, 1, 0, 0, 0);
        //判断是否在区间内
        return TimeTool.isEffectiveDate(nowTime, beginTime, endTime);
    }

    private String getOrderNo(String organizeCode) {
        String orderNo = "";
        BaseResultBean oneCodeResult = syncFuncService.syncSerialNo(new GenSerialNoModel(MesExtConstWords.ORDER_NO_RULE), null, organizeCode, 1);
        if (oneCodeResult != null && oneCodeResult.isSuccess()) {
            orderNo = oneCodeResult.getResultList().get(0).toString();
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.CLOUD_CALL_EXCEPTION.getCode())
                    .setErrorDetail("生成唯一工单号失败")
                    .build();
        }
        return orderNo;
    }
    private static boolean haveJob(String produceTime, String generateTime) {
        String day = DateUtil.formatDate("yyyy-MM-dd", new Date());
        produceTime = day + MesExtConstWords.ONE_SPACE + produceTime;
        return produceTime.equals(generateTime);
    }

    public List<MesWorkOrderExt> findWorkOrder(String organizeCode, String workCenterCode){
        int isOpen = MesEnumUtil.WORK_ORDER_STATUS.OPEN.getValue();
        int isLanded = MesEnumUtil.WORK_ORDER_STATUS.LANDED.getValue();
        List<Integer> statusList = Stream.of(isOpen, isLanded).collect(Collectors.toList());
        DdlPackBean ddlPackBean1 = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(statusList,MesExtConstWords.WORK_ORDER_STATUS,ddlPackBean1);
        DdlPreparedPack.getStringEqualPack(workCenterCode,MesExtConstWords.WORK_CENTER_CODE,ddlPackBean1);
        return mesWorkOrderExtRDao.findByHqlWhere(ddlPackBean1);

    }

    public List<MesProjectConfirm> findProjectConfirm(String organizeCode){
        DdlPackBean ddlPackBean1 = DdlPackBean.getDdlPackBean(organizeCode);
        return mesProjectConfirmRDao.findByHqlWhere(ddlPackBean1);

    }

    public List<MesOrderJob> findOrderJob(String organizeCode, String workCenterCode){
        DdlPackBean ddlPackBean1 = DdlPackBean.getDdlPackBean(organizeCode);
        String day = TimeTool.getToday();
        String startTime = day + MesExtConstWords.APPEND_ZERO_HH_MM_SS;
        String endTime = day + MesExtConstWords.APPEND_A_POINTS;
        int taskType = MesExtEnumUtil.MES_OR_TASK_TYPE.PROCESS_TASK.getValue();
        int orderType = MesExtEnumUtil.MES_OR_ORDER_TYPE.PROJECT_TOUR_CONTRIM.getValue();
        DdlPreparedPack.getNumEqualPack(taskType,MesExtConstWords.TASK_TYPE,ddlPackBean1);
        DdlPreparedPack.getNumEqualPack(orderType,MesExtConstWords.ORDER_TYPE,ddlPackBean1);
        DdlPreparedPack.getStringEqualPack(workCenterCode,MesExtConstWords.WORK_CENTER_CODE,ddlPackBean1);
        DdlPreparedPack.timeBuilder(startTime,endTime,MesExtConstWords.GENERATE_TIME,ddlPackBean1,true);
        return mesOrderJobRDao.findByHqlWhere(ddlPackBean1);

    }

}
