package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.job;

import cn.estsh.i3plus.ext.mes.pcn.api.base.IWorkCenterExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.job.IAntiStaticCheckOrderService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
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.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: wangjie
 * @CreateDate: 2019/8/23 1:16 PM
 * @Description: Pcn处理防静电单据生成JOB
 **/
@Slf4j
@Service
public class AntiStaticCheckOrderService implements IAntiStaticCheckOrderService {

    @Autowired
    private MesAntiStaticCheckRepository antiStaticCheckRepository;

    @Autowired
    private MesAntiStaticCheckDetailRepository antiStaticCheckDetailRepository;

    @Autowired
    private MesOrderRuleRepository orderRuleRepository;

    @Autowired
    private MesOrderJobRepository orderJobRepository;

    @Autowired
    private IWorkCenterExtService workCenterExtService;

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Override
    public void doAntiStaticCheckOrder(String organizeCode) {
        List<MesOrderRule> orderRuleDbList = getOrderRuleList(organizeCode);
        if (CollectionUtils.isEmpty(orderRuleDbList)) {
            log.info("Pcn处理防静电单据生成JOB,未配置单据规则");
            return;
        }

        Map<String, List<MesOrderRule>> workCenterCodeMap = orderRuleDbList.stream()
                .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCenterCode()) && !StringUtils.isEmpty(o.getProduceTime())))
                .collect(Collectors.groupingBy(MesOrderRule::getWorkCenterCode));
        log.info("Pcn处理防静电单据生成JOB,生成包含以下生产线{}", workCenterCodeMap.keySet().toString());

        for (String workCenterCode : workCenterCodeMap.keySet()) {
            if (StringUtils.isEmpty(workCenterCode)) {
                continue;
            }
            List<MesOrderRule> orderRuleList = workCenterCodeMap.get(workCenterCode);
            if (CollectionUtils.isEmpty(orderRuleList)) {
                continue;
            }

            List<MesAntiStaticCheck> antiStaticCheckList = getAntiStaticCheckList(organizeCode, workCenterCode);
            if (CollectionUtils.isEmpty(antiStaticCheckList)) {
                log.info("Pcn处理防静电单据生成JOB,生产线[{}]未配置防静电点检项目", workCenterCode);
                continue;
            }

            log.info("Pcn处理防静电单据生成JOB,生产线[{}]配置了防静电点检项目", workCenterCode);

            List<MesWorkOrderExt> workOrderExtList = findWorkOrderList(organizeCode, workCenterCode);

            for (MesOrderRule orderRule : orderRuleList) {
               if (null == orderRule) {
                   continue;
               }
               String produceTime = orderRule.getProduceTime() + MesPcnExtConstWords.APPEND_SECONDS;
               String shiftCode = getCurShiftCode(orderRule.getShiftCode(), organizeCode, workCenterCode);
               if (StringUtils.isEmpty(shiftCode)) {
                   log.info("Pcn处理防静电单据生成JOB,生产线[{}]防静电单据存在生成时间[{}]的单据未配置班次或生产线未启动班次", workCenterCode, produceTime);
                   continue;
               }
               if (TimeTool.stringParseToDate(TimeTool.getNowTime(MesPcnExtConstWords.TIME_FORMAT)).compareTo(TimeTool.stringParseToDate(produceTime)) >= 0) {
                   List<MesOrderJob> orderJobList = getOrderJobList(organizeCode, workCenterCode, shiftCode, produceTime);
                   if (CollectionUtils.isEmpty(orderJobList)) {
                       if (CollectionUtils.isEmpty(workOrderExtList)) {
                           log.info("Pcn处理防静电单据生成JOB,生产线[{}]还未生成时间[{}]班次[{}]的防静电单据,但未查询到启动或下达的工单", workCenterCode, produceTime, shiftCode);
                           continue;
                       }

                       log.info("Pcn处理防静电单据生成JOB,生产线[{}]正在生成时间[{}]班次[{}]的防静电单据", workCenterCode, produceTime, shiftCode);
                       String orderNo = getOrderNo(organizeCode);
                       if (StringUtils.isEmpty(orderNo)) {
                           log.info("Pcn处理防静电单据生成JOB,生产线[{}]生成时间[{}]班次[{}]的防静电单据时生成单据号失败", workCenterCode, produceTime, shiftCode);
                           continue;
                       }
                       insertAntiStaticCheckOrder(organizeCode, workCenterCode, shiftCode, produceTime, orderNo, antiStaticCheckList);
                   }
               }
            }
        }

    }

    private List<MesAntiStaticCheck> getAntiStaticCheckList(String organizeCode,  String workCenterCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        return antiStaticCheckRepository.findByHqlWhere(packBean);
    }

    private List<MesOrderRule> getOrderRuleList(String organizeCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_TASK_TYPE.PREPARE_TASK.getValue(), MesPcnExtConstWords.TASK_TYPE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.ESD_CHECK.getValue(), MesPcnExtConstWords.ORDER_TYPE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_CREATE_RULE.TIME_TO_CREATE.getValue(), MesPcnExtConstWords.CREATE_RULE, packBean);
        return orderRuleRepository.findByHqlWhere(packBean);
    }

    private List<MesOrderJob> getOrderJobList(String organizeCode, String workCenterCode, String shiftCode, String produceTime) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_TASK_TYPE.PREPARE_TASK.getValue(), MesPcnExtConstWords.TASK_TYPE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.ESD_CHECK.getValue(), MesPcnExtConstWords.ORDER_TYPE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.HANDLER_METHOD.AUTOMATICALLY_CREATED.getValue(), MesPcnExtConstWords.HANDLER_METHOD, packBean);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(shiftCode, MesPcnExtConstWords.SHIFT_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(TimeTool.getToday() + MesPcnExtConstWords.ONE_SPACE + produceTime, MesPcnExtConstWords.GENERATE_TIME, packBean);
        return orderJobRepository.findByHqlWhere(packBean);
    }

    private String getCurShiftCode(String shiftCode, String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(shiftCode)) {
            MesWorkCenterExt workCenterExt = workCenterExtService.getWorkCenterExtByWorkCenterCode(organizeCode, workCenterCode);
            if (null != workCenterExt) {
                shiftCode = workCenterExt.getShiftCode();
            }
        }
        return shiftCode;
    }

    private List<MesWorkOrderExt> findWorkOrderList(String organizeCode, String workCenterCode) {
        List<MesWorkOrderExt> workOrderExtList = null;
        List<MesWorkOrderExt> openList = getWorkOrderList(organizeCode, workCenterCode, MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
        List<MesWorkOrderExt> landedList = getWorkOrderList(organizeCode, workCenterCode, MesPcnExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue());
        if (!CollectionUtils.isEmpty(openList) || !CollectionUtils.isEmpty(landedList)) {
            workOrderExtList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(openList)) {
                workOrderExtList.addAll(openList);
            }
            if (!CollectionUtils.isEmpty(landedList)) {
                workOrderExtList.addAll(landedList);
            }
        }
        return workOrderExtList;
    }

    private List<MesWorkOrderExt> getWorkOrderList(String organizeCode, String workCenterCode, Integer workOrderStatus) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getNumEqualPack(workOrderStatus, MesPcnExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        return workOrderExtRepository.findByHqlWhere(packBean);
    }

    private String getOrderNo(String organizeCode) {
        String orderNo = null;
        try {
            BaseResultBean oneCodeResult = syncFuncService.syncSerialNo(new GenSerialNoModel(MesPcnExtConstWords.ORDER_NO_RULE), null, organizeCode, 1);
            if (oneCodeResult != null && oneCodeResult.isSuccess()) {
                orderNo = oneCodeResult.getResultList().get(0).toString();
            }
        } catch (Exception e) {
        }
        return orderNo;
    }

    private void insertAntiStaticCheckOrder(String organizeCode, String workCenterCode, String shiftCode, String produceTime, String orderNo, List<MesAntiStaticCheck> antiStaticCheckList) {
        MesOrderJob orderJob = new MesOrderJob();
        orderJob.setTaskType(MesPcnExtEnumUtil.MES_OR_TASK_TYPE.PREPARE_TASK.getValue());
        orderJob.setOrderType(MesPcnExtEnumUtil.MES_OR_ORDER_TYPE.ESD_CHECK.getValue());
        orderJob.setHandlerMethod(MesPcnExtEnumUtil.HANDLER_METHOD.AUTOMATICALLY_CREATED.getValue());
        orderJob.setOrderNo(orderNo);
        orderJob.setWorkCenterCode(workCenterCode);
        orderJob.setOrderStatus(MesPcnExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
        orderJob.setOrderDate(TimeTool.getToday());
        orderJob.setWorkTime(orderJob.getOrderDate());
        orderJob.setGenerateTime(orderJob.getOrderDate() + MesPcnExtConstWords.ONE_SPACE + produceTime);
        orderJob.setShiftCode(shiftCode);
        orderJob.setOrganizeCode(organizeCode);
        List<String> workCellCodeList = (antiStaticCheckList.stream()
                .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCellCode()))).map(MesAntiStaticCheck::getWorkCellCode).collect(Collectors.toList()))
                .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        orderJob.setCellCollect(CollectionUtils.isEmpty(workCellCodeList) ? null : org.apache.commons.lang.StringUtils.join(workCellCodeList, MesPcnExtConstWords.COMMA));
        ConvertBean.serviceModelInitialize(orderJob, MesPcnExtConstWords.JOB);
        orderJobRepository.insert(orderJob);

        for (MesAntiStaticCheck antiStaticCheck : antiStaticCheckList) {
            MesAntiStaticCheckDetail antiStaticCheckDetail = new MesAntiStaticCheckDetail();
            BeanUtils.copyProperties(antiStaticCheck, antiStaticCheckDetail, MesPcnExtConstWords.ID);
            antiStaticCheckDetail.setOrderJobNo(orderNo);
            antiStaticCheckDetail.setIsTeamConfirm(MesPcnExtEnumUtil.SHIFT_GROUP_CHECK.NO.getValue());
            antiStaticCheckDetail.setIsQualityConfirm(MesPcnExtEnumUtil.QUALITY_CHECK.NO.getValue());
            ConvertBean.serviceModelInitialize(antiStaticCheckDetail, MesPcnExtConstWords.JOB);
            antiStaticCheckDetailRepository.insert(antiStaticCheckDetail);
        }
    }

}