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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionCustomContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesShippingQueueService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.station.function.MesFunctionChooseShippingGroupService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesConfig;
import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingQueue;
import cn.estsh.i3plus.pojo.mes.model.StationKvBean;
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.util.MesExtEnumUtil;
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.StringJoiner;
import java.util.stream.Collectors;

/**
 * @Description : 发运队列获取工步
 * @Author : wangjie
 **/
@Slf4j
@Service("mesShippingQueueFindStepService")
public class MesShippingQueueFindStepService extends BaseStepService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesProductionDispatchContextStepService productionDispatchContextStepService;

    @Autowired
    private IMesProductionCustomContextStepService productionCustomContextStepService;

    @Autowired
    private MesFunctionChooseShippingGroupService functionChooseShippingGroupService;

    @Autowired
    private IMesShippingQueueService shippingQueueService;

    @Autowired
    private IFsmCommonService fsmCommonService;

    @Autowired
    private IConfigService configService;

    @Override
    public StepResult init(StationRequestBean reqBean) {

        StepResult stepResult = StepResult.getSuccessComplete();

        String endlessLoopReadTimes = fsmCommonService.handleFsmWcpcMapDataForDoScanThenBackValue(reqBean, MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES);
        if (StringUtils.isEmpty(endlessLoopReadTimes)) endlessLoopReadTimes = MesPcnExtConstWords.ENDLESS_LOOP_READ_TIMES_DEFAULT;
        if (productionDispatchContextStepService.dispatchOverEndlessLoopReadTimes(reqBean, endlessLoopReadTimes)) {
            stepThreadSleepAndSendTaskCompleteAndThrowEx(reqBean, new StationResultBean().isWs(false),
                    stepResult.isCompleted(false).msg(String.format("当前未获取到发运队列超过[%s]次!", endlessLoopReadTimes)),
                    MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
        }

        //发送工步内容
        productionCustomContextStepService.sendStepContextMessage(reqBean);

        return stepResult;

    }

    @Override
    public StepResult execute(StationRequestBean reqBean) {

        StationResultBean resultBean = new StationResultBean();

        StepResult stepResult = StepResult.getSuccessComplete();

        //获取上下文信息
        MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);

        //配置错误 抛出异常
        if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());

        //存储生产过程上下文对象
        productionProcessContextStepService.dispatchProductionProcessContext(reqBean, productionProcessContext);

        //扫描信息置空
        String scanInfo = reqBean.resetScanInfo(reqBean.getScanInfo());

        //验证发运组信息是否有效
        List<StationKvBean> resultList = null;

        if (!StringUtils.isEmpty(scanInfo)) {
            //发送工步内容
            productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN);
            //验证扫描的发运组信息是否有效
            resultList = functionChooseShippingGroupService.checkShippingGroupIsValid(reqBean.getOrganizeCode(), scanInfo);
        }

        //扫描的发运组信息无效,获取缓存中的发运组信息
        if (CollectionUtils.isEmpty(resultList)) {
            resultList = productionCustomContextStepService.getFunctionChooseShippingGroupContext(reqBean);
        }

        //缓存中无发运组信息,获取默认配置的发运组代码
        if (CollectionUtils.isEmpty(resultList)) {
            scanInfo = getDefaultShippingGroupCodeCfg(reqBean);
            //验证扫描的发运组信息是否有效
            resultList = functionChooseShippingGroupService.checkShippingGroupIsValid(reqBean.getOrganizeCode(), scanInfo);
        }

        //扫描的发运组信息有效,保存到上下文
        if (!StringUtils.isEmpty(scanInfo) && !CollectionUtils.isEmpty(resultList)) {
            productionCustomContextStepService.dispatchFunctionChooseShippingGroupContext(reqBean, resultList);
        }

        //验证是否存在发运组代码
        if (CollectionUtils.isEmpty(resultList)) {
            if (!StringUtils.isEmpty(scanInfo)) this.sendMessage(reqBean, new StationResultBean().writeDbLog().scanInfo(scanInfo), String.format("扫描信息零件发运组代码[%s]信息无效", scanInfo), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            stepSendGuideAndThrowEx(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), "请扫描或选择零件发运组代码!");
        }

        //发送工步内容
        scanInfo = resultList.stream().filter(o -> (null != o && !o.getKey().equals(MesPcnExtConstWords.CELL_MESSAGE_SOURCE))).map(o -> o.getName() + MesPcnExtConstWords.SQUARE_BRACKETS_L + o.getValue() + MesPcnExtConstWords.SQUARE_BRACKETS_R).collect(Collectors.joining(MesPcnExtConstWords.SEMICOLON));
        productionCustomContextStepService.sendStepContextMessage(reqBean, scanInfo, MesExtEnumUtil.CELL_MESSAGE_SOURCE.SCAN);

        scanInfo = resultList.stream().filter(o -> (null != o && o.getKey().equals(MesPcnExtConstWords.SHIPPING_GROUP_CODE))).findFirst().get().getValue();
        //根据零件发运组代码查询创建时间正序创建状态的一条发运队列
        MesShippingQueue shippingQueue = shippingQueueService.getShippingQueue(reqBean.getOrganizeCode(), scanInfo);

        if (null == shippingQueue) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult,
                    false, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, String.format("当前零件发运组[%s]未匹配到有效的发运队列,持续监听中...", scanInfo),
                    getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
        }

        if (StringUtils.isEmpty(shippingQueue.getVin())) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog().checkRepeat(), stepResult,
                    false, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT, String.format("当前零件发运组[%s]匹配的发运队列单号[%s]VIN为空,请人工处理! 持续监听中...", scanInfo, shippingQueue.getShippingCode()),
                    getStepParams(reqBean), MesPcnExtConstWords.READ_FAILURE_SLEEP, MesPcnExtConstWords.READ_FAILURE_SLEEP_DEFAULT_TIME);
        }

        //保存上下文发运队列信息
        productionDispatchContextStepService.dispatchShippingQueueContext(reqBean, shippingQueue);

        return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, String.format("零件发运组[%s]已匹配发运队列单号[%s]VIN[%s]!", scanInfo, shippingQueue.getShippingCode(), shippingQueue.getVin()));

    }

    private String getDefaultShippingGroupCodeCfg(StationRequestBean reqBean) {
        MesConfig config = configService.getMesConfigByCfgCodeKeyOrg(MesPcnExtConstWords.FUNCTION_CHOOSE_SHIPPING_GROUP,
                new StringJoiner(MesPcnExtConstWords.AND).add(reqBean.getWorkCenterCode()).add(reqBean.getWorkCellCode()).toString(), reqBean.getOrganizeCode());
        return (null != config && !StringUtils.isEmpty(config.getCfgValue())) ? config.getCfgValue() : null;
    }

}
