package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.station.function;

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesEnumExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseSwsService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.function.IFsmModuleFunctionService;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPush;
import cn.estsh.i3plus.pojo.mes.bean.MesQueueOrderPushCellCfg;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.model.ButtonDynamicModel;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import com.alibaba.fastjson.JSONObject;
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.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description : 工位参数按钮事件接口实现【队列推送】
 **/
@Service
public class MesFunctionQueueOrderPushService extends BaseSwsService implements IFsmModuleFunctionService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesQueueOrderPushService queueOrderPushService;

    @Autowired
    private IMesWorkOrderExtService workOrderExtService;

    @Autowired
    private IMesEnumExtService enumExtService;

    @Override
    public Object doCustomApiDispatch(StationRequestBean reqBean, StationResultBean resultBean, ButtonDynamicModel buttonDynamicModel) {

        //页面渲染数据集
        Map<String, Object> resultMap = new HashMap<>();

        //验证参数
        Map<String, String> paramMap = null;
        try {
            paramMap = StringUtils.isEmpty(buttonDynamicModel.getFunctionValue()) ? null : JSONObject.parseObject(buttonDynamicModel.getFunctionValue(), Map.class);
        } catch (Exception e) {
        }
        if (CollectionUtils.isEmpty(paramMap) || StringUtils.isEmpty(BUSI_TYPE.valueOfDescription(paramMap.get(MesPcnExtConstWords.BUSI_TYPE)))) {
            resultMap.put(MesPcnExtConstWords.DATA_TYPE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT.getValue());
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]参数异常!", buttonDynamicModel.getButtonName()));
        }

        //查询
        if (BUSI_TYPE.ONE.value.equals(paramMap.get(MesPcnExtConstWords.BUSI_TYPE))) return queryQueueOrderPush(reqBean, resultMap, paramMap);

        this.sendMessage(reqBean, new StationResultBean().writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue()),
                String.format("[%s]%s: %s", buttonDynamicModel.getButtonName(), BUSI_TYPE.valueOfDescription(paramMap.get(MesPcnExtConstWords.BUSI_TYPE)), JSONObject.toJSONString(paramMap)),
                MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);

        resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PICK.getValue());
        resultMap.put(MesPcnExtConstWords.DATA_TYPE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT.getValue());

        //新增
        if (BUSI_TYPE.TWO.value.equals(paramMap.get(MesPcnExtConstWords.BUSI_TYPE))) insertQueueOrderPush(reqBean, resultBean, buttonDynamicModel, resultMap, paramMap);
        //修改【仅支持修改顺序】
        else if (BUSI_TYPE.THREE.value.equals(paramMap.get(MesPcnExtConstWords.BUSI_TYPE))) updateQueueOrderPush(reqBean, resultBean, buttonDynamicModel, resultMap, paramMap);
        //关闭
        else deleteQueueOrderPush(reqBean, resultBean, buttonDynamicModel, resultMap, paramMap);

        if (!resultMap.containsKey(MesPcnExtConstWords.MESSAGE)) {
            resultMap.put(MesPcnExtConstWords.DATA_TYPE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT.getValue());
            resultMap.put(MesPcnExtConstWords.MESSAGE, String.format("[%s]%s成功!", buttonDynamicModel.getButtonName(), BUSI_TYPE.valueOfDescription(paramMap.get(MesPcnExtConstWords.BUSI_TYPE))));
        }

        return resultMap;

    }

    //查询
    private Map<String, Object> queryQueueOrderPush(StationRequestBean reqBean, Map<String, Object> resultMap, Map<String, String> paramMap) {

        String currentPage = paramMap.get(MesPcnExtConstWords.CURRENT_PAGE);
        String pageSize = paramMap.get(MesPcnExtConstWords.PAGE_SIZE);
        String pushSourceCode = paramMap.get(MesPcnExtConstWords.PUSH_SOURCE_CODE);
        Pager pager = new Pager();
        pager.setCurrentPage(!StringUtils.isEmpty(currentPage) ? Integer.valueOf(currentPage) : MesPcnExtConstWords.ONE);
        pager.setPageSize(!StringUtils.isEmpty(currentPage) ? Integer.valueOf(pageSize) : MesPcnExtConstWords.FIFTY);

        resultMap.put(MesPcnExtConstWords.QUEUE_STATUS, enumExtService.doGetMesEnumByEnumName(reqBean.getOrganizeCode(), MesExtEnumUtil.QUEUE_ORDER_STATUS.class.getSimpleName()));

        //处理排序线推单上下文, 返回推送工位类型对应的配置信息 【目标工位】
        List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList = productionProcessContextStepService.dispatchQueueOrderPushCellCfgContext(reqBean, MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getValue());
        List<String> pushSourceCodeList = CollectionUtils.isEmpty(queueOrderPushCellCfgList) ? null :
                (queueOrderPushCellCfgList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPushSourceCode())))
                        .map(MesQueueOrderPushCellCfg::getPushSourceCode).collect(Collectors.toList())
                ).stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(pushSourceCodeList)) resultMap.put(MesPcnExtConstWords.PUSH_SOURCE_CODE, pushSourceCodeList);
        else {
            pager = PagerHelper.getPager(pager, MesPcnExtConstWords.ZERO);
            resultMap.put(MesPcnExtConstWords.DATA, new ListPager<>(new ArrayList<>(), pager));
            return resultMap;
        }

        paramMap.put(MesPcnExtConstWords.ORGANIZE_CODE, reqBean.getOrganizeCode());
        //根据配置查询生产队列工位推送信息
        resultMap.put(MesPcnExtConstWords.DATA, queueOrderPushService.queryQueueOrderPushListPager(
                paramMap, StringUtils.isEmpty(pushSourceCode) ? pushSourceCodeList : Stream.of(pushSourceCode).collect(Collectors.toList()), pager));
        return resultMap;

    }

    //新增
    private Map<String, Object> insertQueueOrderPush(StationRequestBean reqBean, StationResultBean resultBean,
                                                     ButtonDynamicModel buttonDynamicModel, Map<String, Object> resultMap, Map<String, String> paramMap) {
        if (StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PUSH_SOURCE_CODE))) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]新增:请选择推送来源代码!", buttonDynamicModel.getButtonName()));
        }
        if (StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO))) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]新增:请扫描加工单或客户条码!", buttonDynamicModel.getButtonName()));
        }

        //处理排序线推单上下文, 返回推送工位类型对应的配置信息 【目标工位】
        List<MesQueueOrderPushCellCfg> queueOrderPushCellCfg = productionProcessContextStepService.dispatchQueueOrderPushCellCfgContext(reqBean, MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getValue());
        Optional<MesQueueOrderPushCellCfg> optional = CollectionUtils.isEmpty(queueOrderPushCellCfg) ? null :
                queueOrderPushCellCfg.stream().filter(o -> (null != o && o.getPushSourceCode().equals(paramMap.get(MesPcnExtConstWords.PUSH_SOURCE_CODE)))).findFirst();
        if (null == optional || !optional.isPresent()) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]新增:当前工位未配置推送来源代码[%s]推送工位类型[%s]的配置信息!",
                    buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.PUSH_SOURCE_CODE), MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getDescription()));
        }

        //根据工单或者客户条码 查询生产工单信息(排序)
        MesWorkOrder workOrder = (MesWorkOrder) workOrderExtService.getWorkOrderSort(reqBean.getOrganizeCode(), paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO), true);
        if (null == workOrder) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]新增:根据扫描信息[%s]未匹配到有效的加工单!", buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO)));
        }
        if (!MesExtEnumUtil.ORDER_STATUS.checkSortAllowStatus(workOrder.getWorkOrderStatus())) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]新增:加工单[%s]状态[%s],操作失败!",
                    buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO), MesExtEnumUtil.ORDER_STATUS.valueOfDescription(workOrder.getWorkOrderStatus())));
        }

        //写入工位工单推送信息
        queueOrderPushService.insertQueueOrderPush(reqBean, workOrder, optional.get(), paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP));

        return resultMap;

    }

    //修改【仅支持修改顺序】
    private Map<String, Object> updateQueueOrderPush(StationRequestBean reqBean, StationResultBean resultBean,
                                      ButtonDynamicModel buttonDynamicModel, Map<String, Object> resultMap, Map<String, String> paramMap) {
        if (StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.ID))) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:缺少修改数据的ID参数!", buttonDynamicModel.getButtonName()));
        }
        if (StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ)) && StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP)) && StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_DOWN))) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:缺少工艺顺序号!", buttonDynamicModel.getButtonName()));
        }
        //根据ID查询生产队列工位推送信息
        MesQueueOrderPush queueOrderPush = queueOrderPushService.getQueueOrderPush(reqBean.getOrganizeCode(), Long.valueOf(paramMap.get(MesPcnExtConstWords.ID)));
        if (null == queueOrderPush) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:当前修改的队列ID[%s]对应的数据已不存在!", buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.ID)));
        }
        if (queueOrderPush.getQueueStatus().compareTo(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue()) != 0) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:当前修改的队列信息状态为[%s],不支持修改操作!", buttonDynamicModel.getButtonName(), MesExtEnumUtil.QUEUE_ORDER_STATUS.valueOfDescription(queueOrderPush.getQueueStatus())));
        }

        //处理排序线推单上下文, 返回推送工位类型对应的配置信息 【目标工位】
        List<MesQueueOrderPushCellCfg> queueOrderPushCellCfg = productionProcessContextStepService.dispatchQueueOrderPushCellCfgContext(reqBean, MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getValue());
        Optional<MesQueueOrderPushCellCfg> optional = CollectionUtils.isEmpty(queueOrderPushCellCfg) ? null :
                queueOrderPushCellCfg.stream().filter(o -> (null != o && o.getPushSourceCode().equals(queueOrderPush.getPushSourceCode()))).findFirst();
        if (null == optional || !optional.isPresent()) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:当前工位未配置推送来源代码[%s]推送工位类型[%s]的配置信息!",
                    buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.PUSH_SOURCE_CODE), MesExtEnumUtil.QUEUE_ORDER_CELL_PUSH_TYPE.TARGET.getDescription()));
        }

        Integer processSeq;
        if (!StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ))) processSeq = Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ));
        else if (!StringUtils.isEmpty(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP))) processSeq = queueOrderPushService.getQueueOrderPushCalcSeq(reqBean.getOrganizeCode(), optional.get(), Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_UP)));
        else processSeq = Integer.valueOf(paramMap.get(MesPcnExtConstWords.PROCESS_SEQ_DOWN)) + 1;
        //根据条件修改生产队列工位推送信息
        queueOrderPushService.saveQueueOrderPushByCondition(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
                new Object[]{reqBean.getOrganizeCode(), Long.valueOf(paramMap.get(MesPcnExtConstWords.ID))},
                new String[]{MesPcnExtConstWords.PROCESS_SEQ, MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                new Object[]{processSeq, reqBean.getUserInfo(), TimeTool.getNowTime(true), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});

        return resultMap;
    }

    //关闭
    private Map<String, Object> deleteQueueOrderPush(StationRequestBean reqBean, StationResultBean resultBean,
                                      ButtonDynamicModel buttonDynamicModel, Map<String, Object> resultMap, Map<String, String> paramMap) {
        if (!paramMap.containsKey(MesPcnExtConstWords.ID)) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]关闭:缺少关闭数据的ID参数!", buttonDynamicModel.getButtonName()));
        }
        //根据ID查询生产队列工位推送信息
        MesQueueOrderPush queueOrderPush = queueOrderPushService.getQueueOrderPush(reqBean.getOrganizeCode(), Long.valueOf(paramMap.get(MesPcnExtConstWords.ID)));
        if (null == queueOrderPush) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:当前关闭的队列ID[%s]对应的数据已不存在!", buttonDynamicModel.getButtonName(), paramMap.get(MesPcnExtConstWords.ID)));
        }
        if (queueOrderPush.getQueueStatus().compareTo(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue()) != 0) {
            return packResultMap(reqBean, resultBean, resultMap, String.format("[%s]修改:当前关闭的队列信息状态为[%s],不支持关闭操作!", buttonDynamicModel.getButtonName(), MesExtEnumUtil.QUEUE_ORDER_STATUS.valueOfDescription(queueOrderPush.getQueueStatus())));
        }
        //根据条件修改生产队列工位推送信息状态
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode());
        DdlPreparedPack.getNumEqualPack(Long.valueOf(paramMap.get(MesPcnExtConstWords.ID)), MesPcnExtConstWords.ID, packBean);
        queueOrderPushService.saveQueueOrderPushStatusByDdlPackBean(packBean, reqBean.getUserInfo(), MesExtEnumUtil.QUEUE_ORDER_STATUS.CLOSED.getValue(), reqBean.getWorkCellCode());

        return resultMap;
    }

    //返回提示信息
    private Map<String, Object> packResultMap(StationRequestBean reqBean, StationResultBean resultBean, Map<String, Object> resultMap, String message) {
        this.sendMessage(reqBean, resultBean, message, MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
        resultMap.put(MesPcnExtConstWords.MESSAGE, message);
        return resultMap;
    }

    //业务操作
    enum BUSI_TYPE {

        ONE("1", "查询"),

        TWO("2", "新增"),

        THREE("3", "修改"),

        FOUR("4", "关闭");

        private String value;

        private String description;

        BUSI_TYPE(String value, String description) {

            this.value = value;

            this.description = description;

        }

        public String getValue() {
            return value;
        }

        public String getDescription() {
            return description;
        }

        public static String valueOfDescription(String val) {
            if (StringUtils.isEmpty(val)) return null;
            String tmp = null;
            for (int i = 0; i < values().length; i++) {
                if (val.equals(values()[i].value)) {
                    tmp = values()[i].description;
                }
            }
            return tmp;
        }

    }

}
