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.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCell;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkCellRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ResultBean;
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.stream.Collectors;

/**
 * @Author: xiangming.liao
 * @CreateDate: 2021/02/01 16:33
 * @Description:
 **/
@Service
public class CreatePartCheckService implements IWorkOrderStartService {
    @Autowired
    private MesPartCheckDetailRepository mesPartCheckDetailRDao;
    @Autowired
    private MesOrderRuleRepository mesOrderRuleRDao;
    @Autowired
    private MesOrderJobRepository mesOrderJobRDao;
    @Autowired
    private MesProcessBomRepository mesProcessBomRDao;
    @Autowired
    private MesProcessCellRepository mesProcessCellRDao;
    @Autowired
    private MesWorkCellRepository mesWorkCellRDao;
    @Autowired
    private MesWorkCenterExtRepository mesWorkCenterExtDao;
    @Autowired
    private ISyncFuncService syncFuncService;
    @Override
    public ResultBean execute(MesWorkOrderExt mesWorkOrderExt) {
        String orderNo = mesWorkOrderExt.getOrderNo();
        String partNo = mesWorkOrderExt.getPartNo();
        String workCenterCode = mesWorkOrderExt.getWorkCenterCode();

        //1、查找产线下所有的工位
        List<MesWorkCell> mesWorkCellList = mesWorkCellRDao.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.WORK_CENTER_CODE},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesExtEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
        //2、通过产线和工位去工序工位关系表中查询所有的工序
        List<String> workCells = mesWorkCellList.stream().map(MesWorkCell::getWorkCellCode).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(workCells)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请先维护工序工位关系")
                    .build();
        }
        DdlPackBean pcPackBean = MesHqlPack.getMesAllData(AuthUtil.getOrganize().getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, pcPackBean);
        DdlPreparedPack.getInPackList(workCells, MesExtConstWords.WORK_CELL_CODE, pcPackBean);
        List<MesProcessCell> processCellList = mesProcessCellRDao.findByHqlWhere(pcPackBean);
        List<String> processs = processCellList.stream().map(MesProcessCell::getProcessCode).collect(Collectors.toList());
        //3、通过工序和物料号查询工序BOM
        DdlPackBean bomPackBean = MesHqlPack.getMesAllData(AuthUtil.getOrganize().getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, bomPackBean);
        DdlPreparedPack.getInPackList(processs, MesExtConstWords.PROCESS_CODE, bomPackBean);
        List<MesProcessBom> processBoms = mesProcessBomRDao.findByHqlWhere(bomPackBean);
        if (CollectionUtils.isEmpty(processBoms)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请先维护工序BOM")
                    .build();
        }
        //4、生成单据作业
        MesOrderJob mesOrderJob = createOrderJob(orderNo, workCenterCode);

        //5、生成物料点检详情
        List<MesPartCheckDetail> mesPartCheckDetails = new ArrayList<>();
        processBoms.forEach(pbom -> {
            MesPartCheckDetail dataModel = new MesPartCheckDetail();
            dataModel.setOrderNo(mesOrderJob.getOrderNo());
            dataModel.setWorkOrderNo(mesOrderJob.getWorkOrderNo());
            dataModel.setOrderDate(TimeTool.getToday());
            dataModel.setWorkCenterCode(mesOrderJob.getWorkCenterCode());
            dataModel.setProcessCode(pbom.getProcessCode());
            dataModel.setProcessName(pbom.getProcessName());
            dataModel.setShiftCode(mesOrderJob.getShiftCode());
            //通过工序和产线查询工序工位信息
            DdlPackBean pcPackBeanByPrcs = MesHqlPack.getMesAllData(AuthUtil.getOrganize().getOrganizeCode());
            DdlPreparedPack.getStringEqualPack(pbom.getProcessCode(), MesExtConstWords.PROCESS_CODE, pcPackBeanByPrcs);
            DdlPreparedPack.getStringEqualPack(mesOrderJob.getWorkCenterCode(), MesExtConstWords.WORK_CENTER_CODE, pcPackBeanByPrcs);
            List<MesProcessCell> processCells = mesProcessCellRDao.findByHqlWhere(pcPackBeanByPrcs);
            processCells.forEach(pCell -> {
                dataModel.setWorkCellCode(pCell.getWorkCellCode());
            });
            dataModel.setPartNo(pbom.getPartNo());
            dataModel.setPartNameRdd(pbom.getPartNameRdd());
            dataModel.setItemPartNo(pbom.getItemPartNo());
            dataModel.setItemPartName(pbom.getItemPartName());
            dataModel.setOrderStatus(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
            dataModel.setShiftGroupCheck(MesExtEnumUtil.SHIFT_GROUP_CHECK.NO.getValue());
            dataModel.setQualityCheck(MesExtEnumUtil.QUALITY_CHECK.NO.getValue());
            dataModel.setOrganizeCode(AuthUtil.getOrganize().getOrganizeCode());
            dataModel.setCreateUser(AuthUtil.getSessionUser().getUserName());
            dataModel.setModifyUser(AuthUtil.getSessionUser().getUserName());
            dataModel.setGenerateTime(TimeTool.getNowTime(true));
            ConvertBean.saveOrUpdate(dataModel, AuthUtil.getSessionUser().getUserName());
            mesPartCheckDetailRDao.insert(dataModel);
            mesPartCheckDetails.add(dataModel);
        });
        return ResultBean.success("生成点检单成功").setResultList(mesPartCheckDetails)
                .setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode());
    }

    /**
     * 生成单据作业
     * @param orderNo
     * @param workCenterCode
     * @return
     */
    private MesOrderJob createOrderJob(String orderNo, String workCenterCode) {
        //1、判断单据规则是否存在
        DdlPackBean isRulePackBean = MesHqlPack.getMesAllData(AuthUtil.getOrganize().getOrganizeCode());
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_OR_TASK_TYPE.PREPARE_TASK.getValue(), MesExtConstWords.TASK_TYPE, isRulePackBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_OR_ORDER_TYPE.PART_CHECK.getValue(), MesExtConstWords.ORDER_TYPE, isRulePackBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_OR_CREATE_RULE.WORK_ORDER_CREATE.getValue(), MesExtConstWords.CREATE_RULE, isRulePackBean);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, isRulePackBean);
        List<MesOrderRule> mesOrderRules = mesOrderRuleRDao.findByHqlWhere(isRulePackBean);
        if (CollectionUtils.isEmpty(mesOrderRules)) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("不存在单据规则")
                    .build();
        }
        //组装数据
        MesOrderJob mesOrderJob = new MesOrderJob();
        mesOrderJob.setWorkOrderNo(orderNo);
        mesOrderJob.setTaskType(MesExtEnumUtil.MES_OR_TASK_TYPE.PREPARE_TASK.getValue());
        mesOrderJob.setOrderType(MesExtEnumUtil.MES_OR_ORDER_TYPE.PART_CHECK.getValue());

        //设置单据编号 调用平台生成条码的方法
        List<String> orderNoList = getOrderNoByRuleCode(1,
                MesExtConstWords.ORDER_NO_RULE, new GenSerialNoModel(), AuthUtil.getSessionUser().getUserName(), AuthUtil.getOrganize().getOrganizeCode());
        mesOrderJob.setOrderNo(orderNoList.get(0));
        mesOrderJob.setOrderStatus(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue());
        mesOrderJob.setOrderDate(TimeTool.getToday());

        //通过产线代码获取产线信息
        MesWorkCenterExt workCenterInfo = getWorkCenterInfo(workCenterCode);
        mesOrderJob.setWorkTime(workCenterInfo.getWorkTime());
        mesOrderJob.setOrganizeCode(AuthUtil.getOrganize().getOrganizeCode());
        mesOrderJob.setCreateUser(AuthUtil.getSessionUser().getUserName());
        mesOrderJob.setShiftCode(workCenterInfo.getShiftCode());
        mesOrderJob.setGenerateTime(TimeTool.getNowTime(true));

        //2、规则优先级 1产线班次都为空--》2产线不为空--》3产线班次都不为空
        List<MesOrderRule> allNull = mesOrderRules.stream().filter(m -> StringUtils.isEmpty(m.getWorkCenterCode()) && StringUtils.isEmpty(m.getShiftCode())).collect(Collectors.toList());
        List<MesOrderRule> workCenterCodeNotNull = mesOrderRules.stream().filter(m -> !StringUtils.isEmpty(m.getWorkCenterCode()) && StringUtils.isEmpty(m.getShiftCode())).collect(Collectors.toList());
        List<MesOrderRule> allNotNull = mesOrderRules.stream().filter(m -> !StringUtils.isEmpty(m.getWorkCenterCode()) && !StringUtils.isEmpty(m.getShiftCode())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(allNotNull)) {
            allNotNull.forEach(m -> {
                mesOrderJob.setWorkCenterCode(m.getWorkCenterCode());
            });
            return mesOrderJobRDao.insert(mesOrderJob);
        } else if (!CollectionUtils.isEmpty(workCenterCodeNotNull)) {
            workCenterCodeNotNull.forEach(m -> {
                mesOrderJob.setWorkCenterCode(m.getWorkCenterCode());
            });
            return mesOrderJobRDao.insert(mesOrderJob);
        } else if (!CollectionUtils.isEmpty(allNull)) {
            ConvertBean.saveOrUpdate(mesOrderJob, AuthUtil.getSessionUser().getUserName());
            return mesOrderJobRDao.insert(mesOrderJob);
        }
        return null;
    }

    /**
     * 通过产线获取产线信息
     *
     * @param workCenterCode
     * @return
     */
    private MesWorkCenterExt getWorkCenterInfo(String workCenterCode) {
        MesWorkCenterExt workCenterExt = mesWorkCenterExtDao.getByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.WORK_CENTER_CODE},
                new Object[]{AuthUtil.getOrganize().getOrganizeCode(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesExtEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
        if (null==workCenterExt) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_EXIT.getCode())
                    .setErrorDetail("请维护产线")
                    .build();
        }
        return workCenterExt;
    }

    /**
     * 生成单据编号
     * @param number
     * @param ruleCode
     * @param genSerialNoModel
     * @param userName
     * @param org
     * @return
     */
    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();
        }
    }
}
