package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.busi;

import cn.estsh.i3plus.ext.mes.api.busi.IWorkOrderStartService;
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.platform.common.convert.ConvertBean;
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.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.MesProcessRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ResultBean;
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: xiangming.liao
 * @CreateDate: 2021/02/04 16:33
 * @Description:
 **/
@Service
public class PersonCheckService implements IWorkOrderStartService {
    @Autowired
    private MesWorkCenterExtRepository mesWorkCenterExtRDao;
    @Autowired
    private MesOrderRuleRepository mesOrderRuleRDao;
    @Autowired
    private MesProcessCellRepository mesProcessCellRDao;
    @Autowired
    private MesProcessCheckRepository mesProcessCheckRDao;
    @Autowired
    private MesOrderJobRepository mesOrderJobRDao;
    @Autowired
    private ISyncFuncService syncFuncService;
    @Autowired
    private MesProcessRepository mesProcessRDao;
    @Autowired
    private MesWorkCellRepository mesWorkCellRDao;
    @Autowired
    private MesPersonCheckDetailRepository mesPersonCheckDetailRDao;

    @Override
    public ResultBean execute(MesWorkOrderExt mesWorkOrderExt) {
        List<MesProcessCheck> mesProcessChecks = new ArrayList<>();
        MesOrderRule mesOrderRule = null;
        //根据产线获取产线信息
        MesWorkCenterExt mesWorkCenterExt = mesWorkCenterExtRDao.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED, MesExtConstWords.WORK_CENTER_CODE},
                new Object[]{mesWorkOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), mesWorkOrderExt.getWorkCenterCode()});

        //产线代码、班次代码、单据类型【人员点检】创建规则【工单产生】查询单据作业信息
        mesOrderRule = mesOrderRuleRDao.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED,
                        MesExtConstWords.ORDER_TYPE, MesExtConstWords.CREATE_RULE, MesExtConstWords.WORK_CENTER_CODE, MesExtConstWords.SHIFT_CODE},
                new Object[]{mesWorkOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesExtEnumUtil.MES_OR_ORDER_TYPE.PERSON_CHECK.getValue(),
                        MesExtEnumUtil.MES_OR_CREATE_RULE.WORK_ORDER_CREATE.getValue(), mesWorkOrderExt.getWorkCenterCode(), mesWorkCenterExt.getShiftCode()});

        if (mesOrderRule == null) {
            mesOrderRule = mesOrderRuleRDao.getByProperty(
                    new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED,
                            MesExtConstWords.ORDER_TYPE, MesExtConstWords.CREATE_RULE, MesExtConstWords.WORK_CENTER_CODE},
                    new Object[]{mesWorkOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                            CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesExtEnumUtil.MES_OR_ORDER_TYPE.PERSON_CHECK.getValue(),
                            MesExtEnumUtil.MES_OR_CREATE_RULE.WORK_ORDER_CREATE.getValue(), mesWorkOrderExt.getWorkCenterCode()});

            if (mesOrderRule == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("人员点检的单据规则信息不存在，请检查")
                        .build();
            }
        }

        //根据产线获取产线工序工位信息数据
        List<MesProcessCell> mesProcessCellList = mesProcessCellRDao.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_VALID, MesExtConstWords.IS_DELETED, MesExtConstWords.WORK_CENTER_CODE},
                new Object[]{mesWorkOrderExt.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(),
                        CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), mesWorkOrderExt.getWorkCenterCode()});

        if (CollectionUtils.isEmpty(mesProcessCellList)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("当前产线【%s】在产线工序工位信息中不存在数据", mesWorkOrderExt.getWorkCenterCode())
                    .build();
        }

        //根据工序代码分组
        Map<String, List<MesProcessCell>> processCellmMap = mesProcessCellList.stream().collect(Collectors.groupingBy(MesProcessCell::getProcessCode));
        //获取工序代码集合
        List<String> processCodeList = mesProcessCellList.stream().map(MesProcessCell::getProcessCode).collect(Collectors.toList());

        //根据工序代码集合和零件号为空查询工序点检项目信息
        DdlPackBean packBean = findMesProcessCheck(mesWorkOrderExt.getOrganizeCode(), null, processCodeList);
        List<MesProcessCheck> processCheckListByMotPartNo = mesProcessCheckRDao.findByHqlWhere(packBean);
        if (!CollectionUtils.isEmpty(processCheckListByMotPartNo)) {
            mesProcessChecks.addAll(processCheckListByMotPartNo);
        }

        //根据工序代码集合和零件号查询工序点检项目信息
        packBean = findMesProcessCheck(mesWorkOrderExt.getOrganizeCode(), mesWorkOrderExt.getPartNo(), processCodeList);
        List<MesProcessCheck> processCheckList = mesProcessCheckRDao.findByHqlWhere(packBean);
        if (!CollectionUtils.isEmpty(processCheckList)) {
            mesProcessChecks.addAll(processCheckList);
        }

        if (CollectionUtils.isEmpty(mesProcessChecks)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("根据规则无法查询到工序点检项目数据，请检查")
                    .build();
        }

        //根据单据类型【人员点检】、产线代码和产线信息中的班次代码、生产日期获取人员点检单据作业信息
        packBean = DdlPackBean.getDdlPackBean(mesWorkOrderExt.getOrganizeCode());
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_OR_ORDER_TYPE.PERSON_CHECK.getValue(), MesExtConstWords.ORDER_TYPE, packBean);
        DdlPreparedPack.getStringEqualPack(mesWorkOrderExt.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesWorkCenterExt.getShiftCode(), MesExtConstWords.SHIFT_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(mesWorkCenterExt.getWorkTime(), MesExtConstWords.WORK_TIME, packBean);

        MesOrderJob mesOrderJob = mesOrderJobRDao.getByProperty(packBean);
        if (mesOrderJob == null) {
            String orderNo = insertMesOrderJob(mesWorkOrderExt, mesWorkCenterExt, mesOrderRule.getTaskType());
            insertMesPersonCheckDetail(mesProcessChecks, processCellmMap, orderNo,mesWorkOrderExt);
        }
        return null;
    }

    private String insertMesOrderJob(MesWorkOrderExt mesWorkOrderExt, MesWorkCenterExt mesWorkCenterExt, Integer taskType) {
        // 调用平台生成条码的方法
        List<String> orderNoList = getOrderNoByRuleCode(1,
                MesExtConstWords.ORDER_NO_RULE, new GenSerialNoModel(), mesWorkOrderExt.getCreateUser(), mesWorkOrderExt.getOrganizeCode());

        MesOrderJob mesOrderJob = new MesOrderJob();
        mesOrderJob.setOrganizeCode(mesWorkOrderExt.getOrganizeCode());
        mesOrderJob.setOrderType(MesExtEnumUtil.MES_OR_ORDER_TYPE.PERSON_CHECK.getValue());
        mesOrderJob.setTaskType(taskType);
        mesOrderJob.setOrderNo(orderNoList.get(0));
        mesOrderJob.setWorkCenterCode(mesWorkOrderExt.getWorkCenterCode());
        mesOrderJob.setShiftCode(mesWorkCenterExt.getShiftCode());
        mesOrderJob.setWorkOrderNo(mesWorkOrderExt.getOrderNo());
        mesOrderJob.setOrderStatus(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
        mesOrderJob.setWorkTime(mesWorkCenterExt.getWorkTime());
        mesOrderJob.setOrderDate(TimeTool.getToday());

        ConvertBean.serviceModelInitialize(mesOrderJob, mesWorkOrderExt.getCreateUser());
        mesOrderJobRDao.insert(mesOrderJob);

        return orderNoList.get(0);

    }

    private void insertMesPersonCheckDetail(List<MesProcessCheck> mesProcessChecks, Map<String, List<MesProcessCell>> processCellmMap,String orderNo, MesWorkOrderExt mesWorkOrderExt) {
        // 查询工序表
        /*Map<String, Object> processCodeEntityMap = new HashMap<>();
        try {
            processCodeEntityMap = MesCommonUtil.getCodeEntityMap(mesProcessRDao, MesExtConstWords.PROCESS_CODE, mesProcessChecks.get(0).getOrganizeCode(), "工序表");
        } catch (Exception e) {
        }*/

        /*// 查询工位表
        Map<String, Object> workCellCodeEntityMap = new HashMap<>();
        try {
            workCellCodeEntityMap = MesCommonUtil.getCodeEntityMap(mesWorkCellRDao, MesExtConstWords.WORK_CELL_CODE, mesProcessChecks.get(0).getOrganizeCode(), "工位表");
        } catch (Exception e) {
        }*/


        MesPersonCheckDetail mesPersonCheckDetail;
        for (MesProcessCheck processCheck : mesProcessChecks) {
            mesPersonCheckDetail = new MesPersonCheckDetail();
            mesPersonCheckDetail.setWorkOrderNo(mesWorkOrderExt.getOrderNo());
            mesPersonCheckDetail.setWorkCenterCode(mesWorkOrderExt.getWorkCenterCode());
            mesPersonCheckDetail.setWorkCellCode(processCellmMap.get(processCheck.getProcessCode()).get(0).getWorkCellCode());
            BeanUtils.copyProperties(processCheck, mesPersonCheckDetail, MesExtConstWords.ID);
            mesPersonCheckDetail.setShiftCode(mesWorkOrderExt.getShiftCode());
/*            if (!CollectionUtils.isEmpty(processCodeEntityMap) && processCodeEntityMap.containsKey(mesPersonCheckDetail.getProcessCode())) {
                mesPersonCheckDetail.setProcessName(((MesProcess) processCodeEntityMap.get(mesPersonCheckDetail.getProcessCode())).getProcessName());
            }*/
            mesPersonCheckDetail.setOrderStatus(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
            mesPersonCheckDetail.setOrderNo(orderNo);
            mesPersonCheckDetail.setOrderDate(TimeTool.getToday());
            mesPersonCheckDetail.setShiftGroupCheck(MesExtEnumUtil.SHIFT_GROUP_CHECK.NO.getValue());
            mesPersonCheckDetail.setQualityCheck(MesExtEnumUtil.QUALITY_CHECK.NO.getValue());
            /*if(!CollectionUtils.isEmpty(workCellCodeEntityMap) && workCellCodeEntityMap.containsKey(mesPersonCheckDetail.getWorkCellCode())){
                mesPersonCheckDetail.setWorkCellName(((MesWorkCell)workCellCodeEntityMap.get(mesPersonCheckDetail.getWorkCellCode())).getWorkCellName());
            }*/
            ConvertBean.serviceModelInitialize(mesPersonCheckDetail, mesWorkOrderExt.getCreateUser());
            mesPersonCheckDetailRDao.insert(mesPersonCheckDetail);
        }
    }

    /**
     * @param organizeCode
     * @param partNo
     * @param processCodeList
     * @return
     */
    private static DdlPackBean findMesProcessCheck(String organizeCode, String partNo, List<String> processCodeList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        if (StringUtils.isEmpty(partNo)) {
            DdlPreparedPack.getStringNullPack(MesExtConstWords.PART_NO, packBean);
        }
        DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, packBean);
        DdlPreparedPack.getInPackList(processCodeList, MesExtConstWords.PROCESS_CODE, packBean);
        return packBean;
    }

    public List<String> getOrderNoByRuleCode(int number, String ruleCode, GenSerialNoModel genSerialNoModel, String userName, String org) {
        genSerialNoModel.setRuleCode(ruleCode);
        BaseResultBean<String> serialNumberBean = syncFuncService.syncSerialNo(genSerialNoModel, userName, org, Integer.valueOf(number));
        if (serialNumberBean != null && serialNumberBean.isSuccess()) {
            return serialNumberBean.getResultList();
        } else {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                    .setErrorDetail(serialNumberBean == null ? "条码未生成成功" : serialNumberBean.getErrorMsg())
                    .build();
        }
    }
}
