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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IRouteProcessExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesProduceSnExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseStepService;
import cn.estsh.i3plus.mes.pcn.util.LocaleUtil;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesProcess;
import cn.estsh.i3plus.pojo.mes.bean.MesRouteProcess;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesRouteProcessRepository;
import lombok.extern.slf4j.Slf4j;
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.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @Description : 工步业务-条码工序校验工步
 * @Reference :
 * @Author : wangjie
 * @CreateDate : 2019-07-11
 * @Modify:
 **/
@Slf4j
@Service("sxCheckSnProcessStepService")
public class SxCheckSnProcessStepService extends BaseStepService {

    @Autowired
    private IProduceSnExtService produceSnExtService;

    @Autowired
    private IRouteProcessExtService routeProcessExtService;

    @Autowired
    private MesRouteProcessRepository routeProcessRepository;

    @Override
    public StepResult execute(StationRequestBean reqBean) {
        log.info("SxCheckSnProcessStepService[execute] 参数：{}", reqBean);

        StationResultBean resultBean = new StationResultBean();
        String err;

        if (StringUtils.isEmpty(reqBean.getOrganizeCode())) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少工厂代码");
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        if (StringUtils.isEmpty(reqBean.getSerialNumber())) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "入参缺少产品条码");
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        MesProduceSnExt produceSnExt = produceSnExtService.getProduceSnExtBySn(reqBean.getOrganizeCode(), reqBean.getSerialNumber());
        if (null == produceSnExt) {
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), String.format("条码[%s]无效", reqBean.getSerialNumber()));
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        List<MesRouteProcess> routeProcessAllList = routeProcessRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.IS_DELETED, "routeCode"},
                new Object[]{reqBean.getOrganizeCode(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), reqBean.getRouteCode()},
                " order by seq asc ");
        if (CollectionUtils.isEmpty(routeProcessAllList)) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "流程代码[%s]未关联工序"), reqBean.getRouteCode());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        //根据条码对应的工序代码查询工序信息
        if (!StringUtils.isEmpty(produceSnExt.getProcessCode())) {
            MesProcess processBySn = routeProcessExtService.getProcessByCode(reqBean.getOrganizeCode(), produceSnExt.getProcessCode());
            if (null == processBySn){
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]对应的工序代码[%s]在工序信息中不存在"), produceSnExt.getSerialNumber(), produceSnExt.getProcessCode());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }
            Optional<MesRouteProcess> routeProcessBySn = routeProcessAllList.stream().filter(o -> (null != o && o.getProcessCode().equals(produceSnExt.getProcessCode()))).findFirst();
            if (null == routeProcessBySn || !routeProcessBySn.isPresent()) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]对应的工序代码[%s]不匹配当前流程代码[%s]"), produceSnExt.getSerialNumber(), produceSnExt.getProcessCode(), reqBean.getRouteCode());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }
        }

        //获取当前工位，model中的流程代码、工序代码。查询【MES_流程对应工序表】获取工序排序号
        Optional<MesRouteProcess> routeProcessDbOp = routeProcessAllList.stream().filter(o -> (null != o && o.getProcessCode().equals(reqBean.getProcessCode()))).findFirst();
        if (null == routeProcessDbOp || !routeProcessDbOp.isPresent()) {
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(),
                    "根据工序代码[%s]和流程代码[%s]在流程工序关系信息中不存在数据"), reqBean.getRouteCode(), reqBean.getProcessCode());
            sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        if (!StringUtils.isEmpty(produceSnExt.getProcessCode()) && produceSnExt.getProcessCode().equals(reqBean.getProcessCode())) {
            //检验条码是否已在当前工作单元操作过
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "条码[%s]已经过此工位，不可重复操作"), produceSnExt.getSerialNumber());
            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return StepResult.getNonComplete(err);
        }

        //获取小于当前工序排序号的所有工序代码、是否必过，根据排序号进行正序
        List<MesRouteProcess> routeProcessList = routeProcessAllList.stream().filter(o -> (null != o && o.getSeq().compareTo(routeProcessDbOp.get().getSeq()) < 0)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(routeProcessList)) {
            if (!StringUtils.isEmpty(produceSnExt.getProcessCode()) || !StringUtils.isEmpty(produceSnExt.getNextProcessCode())) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "产品条码[%s]已经过首工位,操作失败,检查当前工位是否属于首工位"), produceSnExt.getSerialNumber());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }
        } else {

            // PS ： OP40，OP70， OP80， OP90 四道工序 均必过
            // 已经经过  OP40，OP70， OP80， 再执行OP70时用此标志判断
            Boolean flag = true;

            //获取条码经过的上道工序与当前工序之间的工序集合
            List<MesRouteProcess> nextProcessList = null;

            for(int i = 0; i < routeProcessList.size(); i ++){
                MesProcess process = routeProcessExtService.getProcessByCode(reqBean.getOrganizeCode(), routeProcessList.get(i).getProcessCode());
                if (process == null){
                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工序代码[%s]在工序信息中不存在"), routeProcessList.get(i).getProcessCode());
                    sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return StepResult.getNonComplete(err);
                }
                if (i == 0) {
                    if (StringUtils.isEmpty(produceSnExt.getProcessCode())) {
                        if (routeProcessList.get(i).getIsNecessary() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()) {
                            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "产品条码[%s]未经过首工位,此工位不可操作"), produceSnExt.getSerialNumber());
                            this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                            return StepResult.getNonComplete(err);
                        }
                    }
                }

                if (!StringUtils.isEmpty(produceSnExt.getProcessCode())) {
                    if(routeProcessList.get(i).getProcessCode().equals(produceSnExt.getProcessCode())) {
                        flag = true;
                        if (routeProcessList.size() > i + 1) {
                            nextProcessList = routeProcessList.subList(i + 1, routeProcessList.size());
                        }
                        break;
                    } else {
                        flag = false;
                    }
                } else {
                    nextProcessList = routeProcessList;
                }

            }

            if (!CollectionUtils.isEmpty(nextProcessList)) {
                for (MesRouteProcess routeProcess : nextProcessList) {
                    //不一致，判断是否是必须必过
                    if(routeProcess.getIsNecessary() == CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue()){
                        err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(),
                                "产品条码[%s]经过的上道工序与当前工序之间还存在必过工序,此工位不可操作"), produceSnExt.getSerialNumber());
                        sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                        return StepResult.getNonComplete(err);
                    }
                }
            }

            // flag = false 代表 经过 OP40，OP70，OP80之后， 再次执行了OP70
            if (!flag) {
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(),
                        "产品条码[%s]已经经过此工位,不可操作"), produceSnExt.getSerialNumber());
                sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                return StepResult.getNonComplete(err);
            }

        }

        return StepResult.getSuccessComplete();
    }

}
