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

import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnTravelExtService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.dao.IProduceSnTravelDao;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ProduceSnTravelModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesProduceSnExtRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseModuleService;
import cn.estsh.i3plus.mes.pcn.util.LocaleUtil;
import cn.estsh.i3plus.mes.pcn.util.PojoAttrUtil;
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.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesStateMachineStatus;
import cn.estsh.i3plus.pojo.mes.model.AttrBean;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.ImppRedis;
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 javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description : 展示组件：生成大本体条码
 * @Reference :
 * @Author :wangjie
 * @CreateDate : 2020-06-26 11:18 上午
 * @Modify:
 **/
@Slf4j
@Service("sxNoumenonPrintBigProcessModuleService")
public class SxNoumenonPrintBigProcessModuleService extends BaseModuleService {

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private IProduceSnTravelDao produceSnTravelDao;

    @Autowired
    private IProduceSnTravelExtService produceSnTravelExtService;

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Resource(name = MesPcnExtConstWords.REDIS_RES_PCN)
    private ImppRedis redisMesPcn;

    private static final String LAST_SELECT_ORDER = "LAST_SELECT_ORDER";

    @Override
    public void init(StationRequestBean reqBean) {
        StationResultBean resultBean = new StationResultBean();
        String err;

        resultBean.setBusiType(MesPcnEnumUtil.STATION_BUSI_TYPE.MODULE_CONTENT.getValue());
        resultBean.setDataType(MesPcnEnumUtil.STATION_DATA_TYPE.CUSTOM.getValue());
        resultBean.setCustomPageName(MesPcnExtConstWords.BIG_PROCESS_PRINT_MODULE);
        resultBean.setDataAttrList(packDataAttrList(reqBean));
        resultBean.setSpecialDisplayData(getStepColIndent(reqBean));

        String lastSelectOrder = getLastSelectOrder(reqBean);
        this.sendMessage(reqBean,  null,"", MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
        if(StringUtils.isEmpty(reqBean.getWorkOrderNo()) && StringUtils.isEmpty(lastSelectOrder)){
            this.sendMessage(reqBean, resultBean);
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请选择工单");
            this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                    .setErrorDetail("请选择工单")
                    .build();
        }

        if(!StringUtils.isEmpty(reqBean.getWorkOrderNo())){
            if(!StringUtils.isEmpty(lastSelectOrder)){
                if(!lastSelectOrder.equals(reqBean.getWorkOrderNo())){
                    putLastSelectOrder(reqBean);
                }
            }else {
                putLastSelectOrder(reqBean);
            }
        }else{
            reqBean.setWorkOrderNo(lastSelectOrder);
        }

        if (StringUtils.isEmpty(reqBean.getWorkOrderNo())) {
            this.sendMessage(reqBean, resultBean);
            err = LocaleUtil.transferLanguage(reqBean.getUserInfo(), "请选择工单");
            this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.GUIDE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                    .setErrorDetail("请选择工单")
                    .build();
        }
        MesWorkOrderExt workOrderExt = workOrderExtService.getWorkOrderExtByOrderNo(reqBean.getOrganizeCode(), reqBean.getWorkOrderNo());

        if(doCheckWorkOrderIsExist(workOrderExt) == false){
            err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工单[%s]不存在"),reqBean.getWorkOrderNo());
            this.sendMessage(reqBean,  null, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                    .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                    .setErrorDetail("工单[%s]不存在")
                    .build();
        }

        List<MesProduceSnTravelExt> produceSnTravelExtList = produceSnTravelExtService.getProduceSnTravelExtListByOrderNoAndProcessCode(
                reqBean.getOrganizeCode(), reqBean.getProcessCode(), reqBean.getWorkCellCode(), reqBean.getWorkOrderNo());

        reqBean.setWorkOrderNo(workOrderExt.getOrderNo());
        resultBean.setResultMap(packResultMap(workOrderExt, produceSnTravelExtList));
        resultBean.setResultList(packResultList(reqBean, workOrderExt));
        this.sendMessage(reqBean, resultBean);

    }

    private boolean doCheckWorkOrderIsExist(MesWorkOrderExt workOrderExt){
        if(workOrderExt == null) {
            return false;
        }else {
            return true;
        }
    }

    private List<MesProduceSnExt> queryProduceSnList(StationRequestBean reqBean, MesWorkOrderExt workOrderExt){
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(workOrderExt.getOrderNo(), MesPcnExtConstWords.WORK_ORDER_NO, packBean);
        return produceSnExtRepository.findByHqlWhere(packBean);
    }

    private List<ProduceSnTravelModel> packResultList(StationRequestBean reqBean, MesWorkOrderExt workOrderExt) {

        List<MesProduceSnExt> produceSnExtList = queryProduceSnList(reqBean, workOrderExt);
        List<ProduceSnTravelModel> modelList = produceSnTravelDao.queryProduceSnTravel(reqBean.getOrganizeCode(), reqBean.getWorkCellCode(), reqBean.getWorkCenterCode(), workOrderExt.getOrderNo());
        System.out.println(modelList);
        List<String> snList = CollectionUtils.isEmpty(modelList) ? new ArrayList<>() :
                modelList.stream().filter(o-> null != o).map(ProduceSnTravelModel::getSerialNumber).collect(Collectors.toList());

        List<MesProduceSnExt> unScanList = CollectionUtils.isEmpty(produceSnExtList) ? null :
                produceSnExtList.stream().filter(o->(null != o && !snList.contains(o.getSerialNumber()))).collect(Collectors.toList());

        unScanList = CollectionUtils.isEmpty(unScanList) ? null :
                unScanList.stream().sorted(Comparator.comparing(MesProduceSnExt::getSerialNumber)).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(unScanList)) {
            for (MesProduceSnExt produceSnExt : unScanList) {
                if (null == produceSnExt) {
                    continue;
                }
                ProduceSnTravelModel model = new ProduceSnTravelModel();
                model.setSerialNumber(produceSnExt.getSerialNumber());
                if (CollectionUtils.isEmpty(modelList)) {
                    modelList = new ArrayList<>();
                }
                modelList.add(model);
            }
        }

        return modelList;
    }

    private Map<String, Object> packResultMap(MesWorkOrderExt workOrderExt ,List<MesProduceSnTravelExt> produceSnTravelExtList) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_NO, workOrderExt.getOrderNo());
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_TYPE_NAME, MesPcnExtEnumUtil.WORK_ORDER_TYPE.valueOfDescription(workOrderExt.getWorkOrderType()));
        resultMap.put(MesPcnExtConstWords.PART_NO, workOrderExt.getPartNo());
        resultMap.put(MesPcnExtConstWords.PART_NAME, workOrderExt.getPartNameRdd());
        resultMap.put(MesPcnExtConstWords.QTY, workOrderExt.getQty());
        resultMap.put(MesPcnExtConstWords.OPERATE_QTY, CollectionUtils.isEmpty(produceSnTravelExtList) ? 0 : produceSnTravelExtList.size());
        return resultMap;
    }

    private List<AttrBean> packDataAttrList(StationRequestBean reqBean) {
        List<AttrBean> attrBeanList = new ArrayList<>();
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.SERIAL_NUMBER, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "产品条码"));
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.MODIFY_DATE_TIME, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "扫描时间"));
        return attrBeanList;
    }

    private String getLastSelectOrderKey(StationRequestBean reqBean) {
        return getCacheKey(reqBean, LAST_SELECT_ORDER);
    }

    private String getLastSelectOrder(StationRequestBean reqBean) {
        return (String) redisMesPcn.getObject(getLastSelectOrderKey(reqBean));
    }

    public void putLastSelectOrder(StationRequestBean reqBean) {
        redisMesPcn.putObject(getLastSelectOrderKey(reqBean), reqBean.getWorkOrderNo(), MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
    }

    private void deleteLastSelectOrder(StationRequestBean reqBean) {
        redisMesPcn.deleteKey(getLastSelectOrderKey(reqBean));
    }



    @Override
    public boolean execute(StationRequestBean reqBean) {
        return true;
    }

    @Override
    public boolean execStateModule(StationRequestBean reqBean, List<MesStateMachineStatus> states, Map<String, String> wcpcMap) {
        init(reqBean);
        return true;
    }


}
