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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesQueueOrderPushService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPartContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
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.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.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.repository.MesQueueOrderPushCellCfgRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesQueueOrderPushRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
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;

@Service
public class MesQueueOrderPushService implements IMesQueueOrderPushService {

    @Autowired
    private MesQueueOrderPushCellCfgRepository queueOrderPushCellCfgRepository;

    @Autowired
    private MesQueueOrderPushRepository queueOrderPushRepository;

    @Override
    public List<MesQueueOrderPushCellCfg> getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode, String workCellCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(workCellCode)) return null;
        return queueOrderPushCellCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE, MesPcnExtConstWords.WORK_CELL_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode, workCellCode});
    }

    @Override
    public List<MesQueueOrderPushCellCfg> getQueueOrderPushCellCfgList(String organizeCode, String workCenterCode) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(workCenterCode)) return null;
        return queueOrderPushCellCfgRepository.findByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.WORK_CENTER_CODE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), workCenterCode});
    }

    //获取当前生产线推单代码中最大的顺序号; 递增步长10,取整10位; 例如:查询=10 >> 返回=20 ;  查询=29 >> 返回=30
    @Override
    public Integer getQueueOrderPushMaxSeq(String organizeCode, MesQueueOrderPushCellCfg queueOrderPushCellCfg) {
        if (StringUtils.isEmpty(organizeCode) || null == queueOrderPushCellCfg) return MesPcnExtConstWords.TEN;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(queueOrderPushCellCfg.getPushSourceCode(), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(queueOrderPushCellCfg.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesPcnExtConstWords.PROCESS_SEQ}, packBean);
        MesQueueOrderPush queueOrderPushDb2MaxSeq = queueOrderPushRepository.getByProperty(packBean);
        return ((null == queueOrderPushDb2MaxSeq || queueOrderPushDb2MaxSeq.getProcessSeq().compareTo(MesPcnExtConstWords.ZERO) == 0)
                ? MesPcnExtConstWords.ONE : (queueOrderPushDb2MaxSeq.getProcessSeq() / MesPcnExtConstWords.TEN + 1)
        ) * MesPcnExtConstWords.TEN;
    }

    //根据条件顺序号查询上一个顺序号,返回加一
    @Override
    public Integer getQueueOrderPushCalcSeq(String organizeCode, MesQueueOrderPushCellCfg queueOrderPushCellCfg, Integer processSeqUp) {
        if (StringUtils.isEmpty(organizeCode) || null == queueOrderPushCellCfg) return MesPcnExtConstWords.TEN;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(queueOrderPushCellCfg.getPushSourceCode(), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(queueOrderPushCellCfg.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getNumberSmallerPackContainsZero(processSeqUp, MesPcnExtConstWords.PROCESS_SEQ, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesPcnExtConstWords.PROCESS_SEQ}, packBean);
        MesQueueOrderPush queueOrderPushDb2MaxSeq = queueOrderPushRepository.getByProperty(packBean);
        if (null == queueOrderPushDb2MaxSeq) return MesPcnExtConstWords.ONE;
        Integer processSeq = queueOrderPushDb2MaxSeq.getProcessSeq() + 1;
        if (processSeq.compareTo(processSeqUp) == 0) return queueOrderPushDb2MaxSeq.getProcessSeq();
        return processSeq;
    }

    //写入工位工单推送信息
    @Override
    public void insertQueueOrderPush(String organizeCode, String userInfo, List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList,
                                     MesProductionPsOutContext productionPsOutContext, MesProductionPartContext productionPartContext) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(userInfo) || null == productionPsOutContext || CollectionUtils.isEmpty(queueOrderPushCellCfgList)) return;
        for (MesQueueOrderPushCellCfg queueOrderPushCellCfg : queueOrderPushCellCfgList) {
            Integer processSeq = getQueueOrderPushMaxSeq(organizeCode, queueOrderPushCellCfg);
            if (null == queueOrderPushCellCfg) continue;
            MesQueueOrderPush queueOrderPush = new MesQueueOrderPush();
            queueOrderPush.setPushSourceCode(queueOrderPushCellCfg.getPushSourceCode());
            queueOrderPush.setProcessSeq(processSeq);
            queueOrderPush.setWorkOrderNo(productionPsOutContext.getWorkOrderNo());
            queueOrderPush.setProductSn(productionPsOutContext.getProductSn());
            queueOrderPush.setCustSn(productionPsOutContext.getCustSn());
            queueOrderPush.setPartNo(productionPsOutContext.getPartNo());
            queueOrderPush.setPartName(productionPsOutContext.getPartName());
            queueOrderPush.setProductSeq(productionPartContext.getProductSeq());
            queueOrderPush.setWorkOrderSeq(productionPartContext.getWorkOrderSeq());
            queueOrderPush.setCarModelCode(productionPartContext.getCarModelCode());
            queueOrderPush.setCustOrderNo(productionPartContext.getCustOrderNo());
            queueOrderPush.setPartProdGroupCode(productionPartContext.getPartProdGroupCode());
            queueOrderPush.setQueueStatus(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue());
            queueOrderPush.setAreaCode(queueOrderPushCellCfg.getAreaCode());
            queueOrderPush.setWorkCenterCode(queueOrderPushCellCfg.getWorkCenterCode());
            queueOrderPush.setSourceWorkCellCode(queueOrderPushCellCfg.getWorkCellCode());
            queueOrderPush.setOrganizeCode(organizeCode);
            ConvertBean.serviceModelInitialize(queueOrderPush, userInfo);
            queueOrderPushRepository.insert(queueOrderPush);
        }
    }

    //写入工位工单推送信息
    @Override
    public void insertQueueOrderPush(StationRequestBean reqBean, MesWorkOrder workOrder, MesQueueOrderPushCellCfg queueOrderPushCellCfg, String processSeqUp) {
        Integer processSeq;
        //获取当前生产线推单代码中最大的顺序号
        if (StringUtils.isEmpty(processSeqUp)) processSeq = getQueueOrderPushMaxSeq(reqBean.getOrganizeCode(), queueOrderPushCellCfg);
        //根据条件顺序号查询上一个顺序号,返回加一
        else processSeq = getQueueOrderPushCalcSeq(reqBean.getOrganizeCode(), queueOrderPushCellCfg, Integer.valueOf(processSeqUp));

        //新增队列
        MesQueueOrderPush queueOrderPush = new MesQueueOrderPush();
        queueOrderPush.setPushSourceCode(queueOrderPushCellCfg.getPushSourceCode());
        queueOrderPush.setProcessSeq(processSeq);
        queueOrderPush.setWorkOrderNo(workOrder.getWorkOrderNo());
        queueOrderPush.setProductSn(workOrder.getWorkOrderNo());
        queueOrderPush.setCustSn(workOrder.getCustSn());
        queueOrderPush.setPartNo(workOrder.getPartNo());
        queueOrderPush.setPartName(workOrder.getPartName());
        queueOrderPush.setProductSeq(workOrder.getProductSeq());
        queueOrderPush.setWorkOrderSeq(workOrder.getWorkOrderSeq());
        queueOrderPush.setCarModelCode(workOrder.getCarModelCode());
        queueOrderPush.setCustOrderNo(workOrder.getCustOrderNo());
        queueOrderPush.setPartProdGroupCode(workOrder.getPartProdGroupCode());
        queueOrderPush.setQueueStatus(MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue());
        queueOrderPush.setAreaCode(reqBean.getAreaCode());
        queueOrderPush.setWorkCenterCode(reqBean.getWorkCenterCode());
        queueOrderPush.setSourceWorkCellCode(reqBean.getWorkCellCode());
        queueOrderPush.setOrganizeCode(reqBean.getOrganizeCode());
        ConvertBean.serviceModelInitialize(queueOrderPush, reqBean.getUserInfo());
        queueOrderPushRepository.insert(queueOrderPush);
    }

    ///根据ID查询生产队列工位推送信息
    @Override
    public MesQueueOrderPush getQueueOrderPush(String organizeCode, Long id) {
        if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(id)) return null;
        return queueOrderPushRepository.getByProperty(
                new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.IS_DELETED, MesPcnExtConstWords.IS_VALID, MesPcnExtConstWords.ID},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), id});
    }

    //根据配置查询创建状态的生产队列工位推送信息
    @Override
    public List<MesQueueOrderPush> getQueueOrderPushList(String organizeCode, List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList) {
        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(queueOrderPushCellCfgList)) return null;
        //搜集推送来源代码 去重; 根据生产线代码,推送来源代码集合查询创建状态的生产队列工位推送信息【工序顺序号正序,创建时间正序】
        List<MesQueueOrderPush> queueOrderPushList = getQueueOrderPushListByStatus(organizeCode, queueOrderPushCellCfgList, CommonEnumUtil.ASC_OR_DESC.ASC.getValue(), MesExtEnumUtil.QUEUE_ORDER_STATUS.CREATE.getValue());
        //条码去重
        queueOrderPushList = CollectionUtils.isEmpty(queueOrderPushList) ? null :
                queueOrderPushList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProductSn()))).distinct()
                        .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesQueueOrderPush::getProductSn))), ArrayList::new));
        if (!CollectionUtils.isEmpty(queueOrderPushList)) queueOrderPushList = queueOrderPushList.stream().filter(o -> null != o)
                .sorted(Comparator.comparing(MesQueueOrderPush::getProcessSeq).thenComparing(MesQueueOrderPush::getCreateDatetime)).collect(Collectors.toList());
        return queueOrderPushList;
    }

    //根据配置查询生产队列工位推送信息
    @Override
    public List<MesQueueOrderPush> getQueueOrderPushListByStatus(String organizeCode, List<MesQueueOrderPushCellCfg> queueOrderPushCellCfgList, Integer ascOrDesc, Integer... queueStatusArr) {

        if (StringUtils.isEmpty(organizeCode) || CollectionUtils.isEmpty(queueOrderPushCellCfgList)) return null;

        //搜集推送来源代码 去重
        List<String> pushSourceCodeList = (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)) return null;

        //根据生产线代码,推送来源代码集合查询入参状态的生产队列工位推送信息【工艺顺序号,创建时间根据条件排序】
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(queueOrderPushCellCfgList.get(0).getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);

        if (null != queueStatusArr && queueStatusArr.length == 1)
            DdlPreparedPack.getNumEqualPack(queueStatusArr[0], MesPcnExtConstWords.QUEUE_STATUS, packBean);
        else if (null != queueStatusArr) DdlPreparedPack.getInPackArray(queueStatusArr, MesPcnExtConstWords.QUEUE_STATUS, packBean);

        if (pushSourceCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(pushSourceCodeList.get(0), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
        else DdlPreparedPack.getInPackList(pushSourceCodeList, MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);

        if (!StringUtils.isEmpty(ascOrDesc)) DdlPreparedPack.getOrderByPack(new Object[]{ascOrDesc, ascOrDesc}, new String[]{MesPcnExtConstWords.PROCESS_SEQ, MesPcnExtConstWords.CREATE_DATE_TIME}, packBean);

        return queueOrderPushRepository.findByHqlWhere(packBean);
    }

    //根据分页条件查询生产队列工位推送信息
    @Override
    public ListPager<MesQueueOrderPush> queryQueueOrderPushListPager(Map<String, String> paramMap, List<String> pushSourceCodeList, Pager pager) {

        DdlPackBean packBean = DdlPackBean.getDdlPackBean(paramMap.get(MesPcnExtConstWords.ORGANIZE_CODE));

        DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.WORK_CENTER_CODE), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.PART_NO), MesPcnExtConstWords.PART_NO, packBean);
        DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.PART_PROD_GROUP_CODE), MesPcnExtConstWords.PART_PROD_GROUP_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(paramMap.get(MesPcnExtConstWords.CUST_ORDER_NO), MesPcnExtConstWords.PART_PROD_GROUP_CODE, packBean);

        DdlPreparedPack.getStringLikerPack(paramMap.get(MesPcnExtConstWords.WORK_ORDER_NO), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        DdlPreparedPack.getStringLikerPack(paramMap.get(MesPcnExtConstWords.CUST_SN), MesPcnExtConstWords.CUST_SN, packBean);

        if (pushSourceCodeList.size() == 1) DdlPreparedPack.getStringEqualPack(pushSourceCodeList.get(0), MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);
        else DdlPreparedPack.getInPackList(pushSourceCodeList, MesPcnExtConstWords.PUSH_SOURCE_CODE, packBean);

        if (paramMap.containsKey(MesPcnExtConstWords.QUEUE_STATUS)) {
            List<Integer> queueStatusList = Arrays.stream(paramMap.get(MesPcnExtConstWords.QUEUE_STATUS).split(MesPcnExtConstWords.COMMA)).map(Integer::parseInt).collect(Collectors.toList());
            if (queueStatusList.size() == 1) DdlPreparedPack.getNumEqualPack(queueStatusList.get(0), MesPcnExtConstWords.QUEUE_STATUS, packBean);
            else DdlPreparedPack.getInPackList(queueStatusList, MesPcnExtConstWords.QUEUE_STATUS, packBean);
        }

        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.DESC.getValue(), CommonEnumUtil.ASC_OR_DESC.DESC.getValue()}, new String[]{MesPcnExtConstWords.PROCESS_SEQ, MesPcnExtConstWords.CREATE_DATE_TIME}, packBean);

        pager = PagerHelper.getPager(pager, queueOrderPushRepository.findByHqlWhereCount(packBean));
        List<MesQueueOrderPush> list = queueOrderPushRepository.findByHqlWherePage(packBean, pager);

        return new ListPager<>(list, pager);
    }

    //根据条件修改生产队列工位推送信息状态
    @Override
    public void saveQueueOrderPushStatusByDdlPackBean(DdlPackBean packBean, String userInfo, Integer queueStatus, String targerWorkCellCode) {
        if (StringUtils.isEmpty(userInfo) || StringUtils.isEmpty(queueStatus)) return;
        queueOrderPushRepository.updateByPropertiesNoSync(
                new String[]{MesPcnExtConstWords.QUEUE_STATUS, MesPcnExtConstWords.TARGET_WORK_CELL_CODE,
                        MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                new Object[]{queueStatus, targerWorkCellCode, userInfo, TimeTool.getNowTime(true), CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY},
                packBean);
    }

    //根据条件修改生产队列工位推送信息
    @Override
    public void saveQueueOrderPushByCondition(String[] conditionName, Object[] conditionValue, String[] propertyName, Object[] propertyValue) {
        queueOrderPushRepository.updateByPropertiesNoSync(conditionName, conditionValue, propertyName, propertyValue);
    }


}
