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


import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesConfigService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionRecordService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesWorkOrderService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.JsonUtilTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.base.util.StringUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord;
import cn.estsh.i3plus.pojo.mes.bean.MesShift;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.repository.MesProductionRecordRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesShiftRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.i3plus.pojo.model.wms.WmsJobParamModel;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.init.ApplicationProperties;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 根据前一天待报工记录数插入工单并报工
 * @version 1.0
 * @date 2024/6/26 10:26
 **/
@Slf4j
@DisallowConcurrentExecution
@Component
@ApiOperation("根据前一天待报工记录数插入工单并报工job")
public class MesReportWorkByPreDayJob extends BaseMesScheduleJob {

    @Autowired
    private IMesWorkOrderService workOrderService;

    @Autowired
    private MesProductionRecordRepository productionRecordRao;
    @Autowired
    private MesShiftRepository mesShiftRepository;
    @Autowired
    private IMesConfigService configService;

    @Autowired
    private IMesProductionRecordService productionRecordService;

    public MesReportWorkByPreDayJob() {
        super(MesReportWorkByPreDayJob.class, "根据前一天待报工记录数插入工单并报工JOB");
    }

    @Override
    public void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties) {
        List<WmsJobParamModel> wmsJobParamModelList = JsonUtilTool.toList(this.getJobParam(), WmsJobParamModel.class);
        String userName = "REPORT_PRE_DAY_JOB";
        if (!CollectionUtils.isEmpty(wmsJobParamModelList)) {
            for (WmsJobParamModel wmsJobParamModel : wmsJobParamModelList) {
                //遍历系统参数指定的产线获取对应班次，找到早班的开始时间，
                String workCenterCodes = configService.getCfgValue(wmsJobParamModel.getOrganizeCode(), "MES_PCN_WORK_CENTER_NO");
                List<String> workCenterCodeList = Arrays.asList(workCenterCodes.split(","));

                for (String workCenterCode : workCenterCodeList) {
                    DdlPackBean packBean = DdlPackBean.getDdlPackBean(wmsJobParamModel.getOrganizeCode());
                    DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", packBean);
                    List<MesShift> mesShiftList = mesShiftRepository.findByHqlWhere(packBean);
                    //1.获取生产加工记录production_record表中，report_status为待汇报状态的工单
                    List<MesProductionRecord> mesProductionRecordList = workOrderService.getPreDayReportMesProductionRecord(wmsJobParamModel.getOrganizeCode(), mesShiftList, workCenterCode);
                    if (CollectionUtils.isEmpty(mesProductionRecordList)) {
                        continue;
                    }
                    Map<String,List<MesProductionRecord>> recordMap = mesProductionRecordList.stream().collect(Collectors.groupingBy(sn -> sn.getWorkCenterCode() + "=" + sn.getPartNo()));
                    for (Map.Entry<String, List<MesProductionRecord>> entry : recordMap.entrySet()) {
                        String k = entry.getKey();
                        List<MesProductionRecord> v = entry.getValue();
                        try {
                            LOGGER.info("产线=-零件号:{},:{},报工mesProductionRecordList:{}",k, v.size());
                            //3.插入生产工单表,根据产线和零件号会创建又给工单
                            MesWorkOrder mesWorkOrder = workOrderService.insertMesWorkOrder(v, mesShiftList, wmsJobParamModel.getOrganizeCode(), userName);
                            if (mesWorkOrder == null) {
                                continue;
                            }
                            LOGGER.info("产线:{}报工mesWorkOrder:{}", workCenterCode, mesWorkOrder.getWorkOrderNo());
                            //4.根据产线+物料产生的工单报工
                            List<MesProductionRecord> mesProductionRecords = new ArrayList<>();
                            try {
                                mesProductionRecords = v.stream().filter(
                                        w -> w.getWorkCenterCode().equalsIgnoreCase(mesWorkOrder.getWorkCenterCode())
                                                && w.getPartNo().equalsIgnoreCase(mesWorkOrder.getPartNo())).collect(Collectors.toList());
                                workOrderService.doPcnJobProductReport(mesProductionRecords, mesShiftList, wmsJobParamModel.getOrganizeCode(), userName, mesWorkOrder);

                                for (MesProductionRecord mesProductionRecord : mesProductionRecords) {

                                    if (StringUtil.isEmpty(mesProductionRecord.getWorkOrderNo())) {
                                        mesProductionRecord.setWorkOrderNo(mesWorkOrder.getWorkOrderNo());
                                    }
                                    mesProductionRecord.setReportStatus(MesExtEnumUtil.REPORT_STATUS.REPORT_STATUS_20.getValue());
                                    mesProductionRecord.setSystemSyncStatus(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue());
                                    ConvertBean.serviceModelUpdate(mesProductionRecord, userName);
                                    mesProductionRecord.setModifyDatetime((new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")).format(new Date()));

                                }
                                productionRecordRao.saveAll(mesProductionRecords);
                            } catch (ImppBusiException e) {
                                List<String> snList = mesProductionRecords.stream().map(MesProductionRecord::getProductSn).collect(Collectors.toList());
                                String errorMsg = StringUtil.isEmpty(e.getErrorDetail()) ? e.getErrorMsg() : e.getErrorDetail();
                                LOGGER.info("条码:{}报工失败,{}", snList, errorMsg);
                                for (MesProductionRecord mesProductionRecord : mesProductionRecords) {
                                    productionRecordService.updateProductionRecord(mesProductionRecord.getOrganizeCode(), userName, mesProductionRecord.getId(), errorMsg);
                                }
                            }
                        } catch (ImppBusiException e) {
                            List<String> snList = v.stream().map(MesProductionRecord::getProductSn).collect(Collectors.toList());
                            String errorMsg = StringUtil.isEmpty(e.getErrorDetail()) ? e.getErrorMsg() : e.getErrorDetail();
                            LOGGER.info("条码:{}报工失败,{}", snList, errorMsg);
                            for (MesProductionRecord mesProductionRecord : v) {
                                productionRecordService.updateProductionRecord(mesProductionRecord.getOrganizeCode(), userName, mesProductionRecord.getId(), errorMsg);
                            }
                        }
                    }
                }
            }
        }else{
            log.info("排序报工job 参数不能为空");
        }
    }
}
