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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxProduceSnExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesProduceSnExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesWorkOrderExt;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.jx.JxSnWorkCellScanModel;
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.actor.shipping.dispatch.IFsmRouteDataService;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesProduceSn;
import cn.estsh.i3plus.pojo.mes.bean.MesRouteProcess;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
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;

/**
 * @Author: wangjie
 * @CreateDate: 2021/01/18 11:41 上午
 * @Description:
 **/
@Slf4j
@Service
public class JxProduceSnExtService implements IJxProduceSnExtService {

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private IFsmRouteDataService fsmRouteDataService;

    @Override
    public MesProduceSnExt getProduceSnExtDb(String organizeCode, String serialNumber, String productSn) {
        if (StringUtils.isEmpty(organizeCode) || (StringUtils.isEmpty(serialNumber) && StringUtils.isEmpty(productSn))) return null;
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(serialNumber, MesPcnExtConstWords.SERIAL_NUMBER, packBean);
        DdlPreparedPack.getStringEqualPack(productSn, MesPcnExtConstWords.PRODUCT_SN, packBean);
        return produceSnExtRepository.getByProperty(packBean);
    }

    @Override
    public void doPackSnExtProcess(StationRequestBean reqBean, MesProduceSnExt produceSnExt) {
        if (null == reqBean || null == produceSnExt) return;

        List<MesRouteProcess> routeProcessList = fsmRouteDataService.getCachedFsmRouteProcessData(reqBean);

        if (CollectionUtils.isEmpty(routeProcessList)) return;

        produceSnExt.setRouteCode(reqBean.getRouteCode());
        produceSnExt.setProcessCode(reqBean.getProcessCode());
        produceSnExt.setNextProcessCode(getNextProcessCode(reqBean.getProcessCode(), routeProcessList));

        if (produceSnExt.getWorkCenterCode().equals(reqBean.getWorkCenterCode())) produceSnExt.setWorkCellCode(reqBean.getWorkCellCode());

    }

    @Override
    public void doCheckIsNeedPackSnExtProcess(StationRequestBean reqBean, MesProduceSnExt produceSnExt) {
        if (null == reqBean || null == produceSnExt) return;

        if (reqBean.getWcpcMap().containsKey(MesPcnExtConstWords.PROCESS_MERGE_FLAG)) return;

        doPackSnExtProcess(reqBean, produceSnExt);

    }

    private String getNextProcessCode(String processCode, List<MesRouteProcess> routeProcessList) {
        Optional<MesRouteProcess> routeProcessOp = routeProcessList.stream().filter(o -> (null != o && o.getProcessCode().equals(processCode))).findFirst();
        if (null == routeProcessOp || !routeProcessOp.isPresent()) return null;
        return routeProcessOp.get().getNextProcess();
    }

    @Override
    public void clearProduceSnProcess(MesProduceSnExt produceSnExt) {
        if (null == produceSnExt) return;
        produceSnExt.setRouteCode(null);
        produceSnExt.setProcessCode(null);
        produceSnExt.setWorkCellCode(null);
    }

    @Override
    public List<String> getBiggerCurProcessList(StationRequestBean requestBean) { return fsmRouteDataService.getBiggerCurProcessList(requestBean); }

    @Override
    public Integer getSnCompleteQtyByProcessList(List<MesProduceSnExt> produceSnList, List<String> processCodeList) {
        List<MesProduceSnExt> completeList = (CollectionUtils.isEmpty(processCodeList) || CollectionUtils.isEmpty(produceSnList)) ? null :
                produceSnList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getProcessCode()) && processCodeList.contains(o.getProcessCode()))).collect(Collectors.toList());
        return CollectionUtils.isEmpty(completeList) ? MesPcnExtConstWords.ZERO : completeList.size();
    }

    @Override
    public List<JxSnWorkCellScanModel> packSnWorkCellScanListByProcessList(List<MesProduceSnExt> produceSnList, List<String> processCodeList) {
        if (CollectionUtils.isEmpty(produceSnList) || CollectionUtils.isEmpty(processCodeList)) return null;

        produceSnList = produceSnList.stream().filter(o -> null != o).sorted(Comparator.comparing(MesProduceSn::getModifyDatetime).reversed()).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(produceSnList) && produceSnList.size() > 20) produceSnList = produceSnList.subList(0, 20);

        List<JxSnWorkCellScanModel> resultList = null;

        Integer index = 1;
        for (MesProduceSnExt produceSnExt : produceSnList) {
            if (null == produceSnExt) continue;
            if (CollectionUtils.isEmpty(resultList)) resultList = new ArrayList<>();
            JxSnWorkCellScanModel result = new JxSnWorkCellScanModel();
            BeanUtils.copyProperties(produceSnExt, result);

            if (!StringUtils.isEmpty(produceSnExt.getProcessCode()) && processCodeList.contains(produceSnExt.getProcessCode())) result.statusName("已完成").color(MesPcnExtConstWords.GREEN);
            else if (MesPcnExtEnumUtil.SN_OPERATE_TYPE.REPAIR.getValue() == produceSnExt.getOperateType()) result.statusName("返修中").color(MesPcnExtConstWords.YELLOW);
            else result.statusName("未完成");

            resultList.add(result.qcStatusName(MesPcnExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(produceSnExt.getQcStatus())).manageCode(produceSnExt.getTrayNo()).index(index));
            index ++;
        }

        return resultList;
    }

    @Override
    public Map<String, Object> packSnWorkCellScanResultMap(MesWorkOrderExt workOrderExt, Integer snCompleteQty) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put(MesPcnExtConstWords.CUR_WORK_ORDER_NO, workOrderExt.getOrderNo());
        resultMap.put(MesPcnExtConstWords.PART_NO, workOrderExt.getPartNo());
        resultMap.put(MesPcnExtConstWords.PART_NAME_RDD, workOrderExt.getPartNameRdd());
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_TYPE, workOrderExt.getWorkOrderType());
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_TYPE_NAME, MesPcnExtEnumUtil.WORK_ORDER_TYPE.valueOfDescription(workOrderExt.getWorkOrderType()));
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS, workOrderExt.getWorkOrderStatus());
        resultMap.put(MesPcnExtConstWords.WORK_ORDER_STATUS_NAME, MesPcnExtEnumUtil.WORK_ORDER_STATUS.valueOfDescription(workOrderExt.getWorkOrderStatus()));
        resultMap.put(MesPcnExtConstWords.QTY, workOrderExt.getQty().intValue());
        resultMap.put(MesPcnExtConstWords.COMPLETE_QTY, snCompleteQty);
        return resultMap;
    }

    @Override
    public Boolean checkPorceCenterPassPwd(StationRequestBean reqBean, String pwd) {
        Map<String, String> wcpcMap = fsmRouteDataService.doHandleFsmWcpcMapData(reqBean);
        String pwdCfg = (CollectionUtils.isEmpty(wcpcMap) || !wcpcMap.containsKey(MesPcnExtConstWords.PWD)) ? null : wcpcMap.get(MesPcnExtConstWords.PWD);
        if (StringUtils.isEmpty(pwdCfg) || (!StringUtils.isEmpty(pwd) && pwdCfg.equals(pwd))) return true;
        return false;
    }

}