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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IErrorLineOffService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesErrorLineOff;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkOrderExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ErrorLineOffModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MissingPartFreConfirmModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesWorkOrderExtRepository;
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.platform.common.tool.MathOperation;
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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;

/**
 * @Description : 展示组件：半成品异常下线缺件-补件确认
 * @Reference :
 * @Author :wangjie
 * @CreateDate : 2020-06-26 11:18 上午
 * @Modify:
 **/
@Slf4j
@Service("sxMissingPartFreConfirmModuleService")
public class SxMissingPartFreConfirmModuleService extends BaseModuleService {

    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;

    @Autowired
    private IErrorLineOffService errorLineOffService;

    @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.MISSING_PART_FRE_CONFIRM_MODEL);
        resultBean.setDataAttrList(packDataAttrList(reqBean));
        resultBean.setSpecialDisplayData(getStepColIndent(reqBean));

        MissingPartFreConfirmModel missingPartFreConfirmModel = getWorkOrderExtModel(reqBean);
        if (null == missingPartFreConfirmModel) {
            if (!StringUtils.isEmpty(reqBean.getWorkOrderNo())) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put(MesPcnExtConstWords.WORK_ORDER_NO, reqBean.getWorkOrderNo());
                resultBean.setResultMap(resultMap);
                this.sendMessage(reqBean, resultBean);

                if (MesPcnEnumUtil.ACTOR_RECEIVE_STRATEGY.WS_CMD_INIT_MODULE.getCode().equals(reqBean.getBusiType())) {
                    err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "工单[%s]不能在工位[%s]操作"), reqBean.getWorkOrderNo(), reqBean.getWorkCellCode());
                    this.sendMessage(reqBean, resultBean, 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]不能在工位[%s]操作", reqBean.getWorkOrderNo(), reqBean.getWorkCellCode())
                            .build();
                }

            } else {
                if (!CollectionUtils.isEmpty(resultBean.getResultMap())) {
                    resultBean.getResultMap().remove(MesPcnExtConstWords.WORK_ORDER_NO);
                }
                this.sendMessage(reqBean, resultBean);
                err = String.format(LocaleUtil.transferLanguage(reqBean.getUserInfo(), "生产线[%s]暂无缺件状态的工单"), reqBean.getWorkCenterCode());
                this.sendMessage(reqBean, resultBean, err, MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT);
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                        .setErrorDetail("生产线[%s]暂无缺件状态的工单", reqBean.getWorkCenterCode())
                        .build();
            }
        }

        reqBean.setWorkOrderNo(missingPartFreConfirmModel.getWorkOrderNo());
        resultBean.setResultMap(packResultMap(missingPartFreConfirmModel));
        resultBean.setResultList(missingPartFreConfirmModel.getErrorLineOffList());
        this.sendMessage(reqBean, resultBean);
    }

    private Map<String, Object> packResultMap(MissingPartFreConfirmModel model) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_NO, model.getWorkOrderNo());
        resultMap.put(MesPcnExtConstWords.MISSING_QTY, model.getMissingQty());
        resultMap.put(MesPcnExtConstWords.PART_NO, model.getPartNo());
        resultMap.put(MesPcnExtConstWords.PART_NAME, model.getPartName());
        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.FRE_STATUS_NAME, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "状态"));
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.FRE_TIME, LocaleUtil.transferLanguage(reqBean.getUserInfo(), "确认时间"));
        return attrBeanList;
    }

    private MissingPartFreConfirmModel getWorkOrderExtModel(StationRequestBean reqBean) {
        List<MissingPartFreConfirmModel> modelList = new ArrayList<>();
        List<Integer> statusList = Arrays.asList(
                MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(),
                MesPcnExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue(),
                MesPcnExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());
        for (Integer status : statusList) {
            MissingPartFreConfirmModel model = getWorkOrderExtByStatus(reqBean, status);
            if (null != model) {
                modelList.add(model);
            }
        }
        if (!CollectionUtils.isEmpty(modelList)) {
            modelList = modelList.stream().sorted(Comparator.comparing(MissingPartFreConfirmModel::getSeq)).collect(Collectors.toList());
            return modelList.get(0);
        }
        return null;
    }

    private MissingPartFreConfirmModel getWorkOrderExtByStatus(StationRequestBean reqBean, int status) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(reqBean.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(reqBean.getWorkCenterCode(), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringEqualPack(reqBean.getAreaCode(), MesPcnExtConstWords.AREA_CODE, packBean);
        DdlPreparedPack.getNumEqualPack(status, MesPcnExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_SN_CREATE_STATUS.CREATED.getValue(), MesPcnExtConstWords.SN_CREATE_STATUS, packBean);
        DdlPreparedPack.getStringEqualPack(reqBean.getWorkOrderNo(), MesPcnExtConstWords.ORDER_NO, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.SEQ}, packBean);
        List<MesWorkOrderExt> workOrderExtList = workOrderExtRepository.findByHqlWhere(packBean);
        workOrderExtList =  CollectionUtils.isEmpty(workOrderExtList) ? null :
                workOrderExtList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getMissingQty()) &&
                        MathOperation.compareTo(o.getMissingQty(), new Double(0)) > 0)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(workOrderExtList)) {
            for (MesWorkOrderExt workOrderExt : workOrderExtList) {
                if (null == workOrderExt) {
                    continue;
                }
                List<MesErrorLineOff> errorLineOffList = errorLineOffService.getErrorLineOffListByWorkOrderNo(reqBean.getOrganizeCode(), workOrderExt.getOrderNo());
                List<MesErrorLineOff> unFreList = CollectionUtils.isEmpty(errorLineOffList) ? null :
                        errorLineOffList.stream().filter(o -> (null != o && CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == o.getFreStatus())).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(unFreList)) {
                    MissingPartFreConfirmModel model = new MissingPartFreConfirmModel();
                    model.setWorkOrderNo(workOrderExt.getOrderNo());
                    model.setSeq(workOrderExt.getSeq());
                    model.setPartNo(workOrderExt.getPartNo());
                    model.setPartName(workOrderExt.getPartNameRdd());
                    model.setMissingQty(new Double(unFreList.size()));
                    model.setErrorLineOffList(packErrorLineOffList(errorLineOffList, reqBean.getUserInfo()));
                    return model;
                }
            }
        }
        return null;
    }

    private List<ErrorLineOffModel> packErrorLineOffList(List<MesErrorLineOff> errorLineOffList, String userInfo) {
        List<ErrorLineOffModel> modelList = new ArrayList<>();
        for (MesErrorLineOff errorLineOff : errorLineOffList) {
            if (null == errorLineOff) {
                continue;
            }
            ErrorLineOffModel model = new ErrorLineOffModel();
            BeanUtils.copyProperties(errorLineOff, model, MesPcnExtConstWords.ID);
            model.setFreStatusName(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue() == model.getFreStatus() ? MesPcnExtConstWords.EMPTY : LocaleUtil.transferLanguage(userInfo, "已补件"));
            modelList.add(model);
        }
        return modelList.stream().sorted(Comparator.comparing(ErrorLineOffModel::getModifyDatetime).reversed()).collect(Collectors.toList());
    }

    @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;
    }

}
