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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu3.ISxEsopCenterActionService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.bu3.SxEsopCenterDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
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.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/7/12 9:59
 **/
@Slf4j
public class SxEsopCenterActionHandChangeService implements ISxEsopCenterActionService {

    private MesWorkOrderRepository workOrderRepository;

    private ISxEsopCenterActionService actionService;

    public SxEsopCenterActionHandChangeService(ISxEsopCenterActionService actionService) {
        this.actionService = actionService;
        workOrderRepository = (MesWorkOrderRepository) SpringContextsUtil.getBean("mesWorkOrderRepository");
    }

    @Override
    public SxEsopCenterDataModel exec(SxEsopCenterDataModel data) {
        List<MesWorkOrder> workOrderList = getOpenedWorkOrderListByCenter(data);

        Integer index = getCurWorkOrderIndex(data, workOrderList);

        Integer nextIndex = getNextWorkOrderIndex(data, workOrderList, index);

        return actionService.exec(data.workOrderNo(workOrderList.get(nextIndex).getOrderNo()));
    }

    @Override
    public void check(SxEsopCenterDataModel data) {
        if (StringUtils.isEmpty(data.getProcessCode()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("作业指导书:入参缺失必要参数工序代码[processCode]")
                    .build();
        if (StringUtils.isEmpty(data.getWorkOrderNo()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("作业指导书:入参缺失必要参数生产工单号[workOrderNo]")
                    .build();
        if (StringUtils.isEmpty(data.getHandFlag()))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("作业指导书:入参缺失必要参数手动切替方式[handFlag]")
                    .build();
    }

    private List<MesWorkOrder> getOpenedWorkOrderListByCenter(SxEsopCenterDataModel data) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(data.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(data.getAreaCode(), MesPcnExtConstWords.AREA_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(data.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(), MesPcnExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.SEQ}, packBean);
        return workOrderRepository.findByHqlWhere(packBean);
    }

    private Integer getCurWorkOrderIndex(SxEsopCenterDataModel data, List<MesWorkOrder> workOrderList) {
        if (CollectionUtils.isEmpty(workOrderList))
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("作业指导书:生产线[%s]暂无启动状态生产工单,操作失败", data.getWorkCenterCode())
                    .build();
        AtomicInteger index = new AtomicInteger();
        Optional<MesWorkOrder> orderOp = workOrderList.stream().filter(o -> {
            index.getAndIncrement();
            return null != o && o.getOrderNo().equals(data.getWorkOrderNo());
        }).findFirst();
        if (null == orderOp || !orderOp.isPresent())
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                    .setErrorDetail("作业指导书:生产线[%s]当前展示的生产工单[%s]状态已经不是启动状态,操作失败", data.getWorkCenterCode(), data.getWorkOrderNo())
                    .build();
        return index.get() - 1;
    }

    private Integer getNextWorkOrderIndex(SxEsopCenterDataModel data, List<MesWorkOrder> workOrderList, Integer index) {
        if (CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() == data.getHandFlag()) {
            if (index.compareTo(0) == 0 || workOrderList.size() == 1)
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("作业指导书:生产线[%s]当前展示的生产工单[%s]上面已无启动状态的生产工单,操作失败", data.getWorkCenterCode(), data.getWorkOrderNo())
                        .build();
            else return index - 1;
        } else {
            if (index.compareTo(workOrderList.size() - 1) >= 0)
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("作业指导书:生产线[%s]当前展示的生产工单[%s]下面已无启动状态的生产工单,操作失败", data.getWorkCenterCode(), data.getWorkOrderNo())
                        .build();
            else return index + 1;
        }
    }
}
