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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.bu3.ISxEsopCenterRemainCfgService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.bean.MesEsopCenterRemainCfg;
import cn.estsh.i3plus.ext.mes.pcn.pojo.repository.MesEsopCenterRemainCfgRepository;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
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.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkOrder;
import cn.estsh.i3plus.pojo.mes.repository.MesWorkOrderRepository;
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.StringUtils;

import javax.annotation.Resource;
import java.util.StringJoiner;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/7/12 9:59
 **/
@Slf4j
@Service
public class SxEsopCenterRemainCfgService implements ISxEsopCenterRemainCfgService {

    @Autowired
    private MesEsopCenterRemainCfgRepository esopCenterRemainCfgRepository;

    @Autowired
    private MesWorkOrderRepository workOrderRepository;

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

    @Override
    public MesEsopCenterRemainCfg getEsopCenterRemainCfg(String organizeCode, String workCenterCode) {
        return esopCenterRemainCfgRepository.getByProperty(
                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});
    }

    @Override
    public String doCachedEsopCenterRemainCfg(String organizeCode, String workCenterCode) {
        MesEsopCenterRemainCfg esopCenterRemainCfgDb = getEsopCenterRemainCfg(organizeCode, workCenterCode);
        if (null == esopCenterRemainCfgDb) return null;
        redisMesPcn.putHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_REMAIN_CFG, esopCenterRemainCfgDb.getRemainQty().toString(), MesEnumUtil.EXPIRE_TIME.NEVER.getValue());
        log.info("工厂{}生产线{}缓存作业指导书剩余切替数量{}成功", organizeCode, workCenterCode, esopCenterRemainCfgDb.getRemainQty());
        return esopCenterRemainCfgDb.getRemainQty().toString();
    }

    @Override
    public String doCachedOrderByEsopCenterRemainCfg(String organizeCode, String workCenterCode, MesWorkOrder workOrder) {
        try {
            if (null == workOrder) return null;
            String curCachedCfg = (String) redisMesPcn.getHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_REMAIN_CFG);
            String curCachedExecOrder = getCachedOrderByEsopCenter(organizeCode, workCenterCode);
            if (StringUtils.isEmpty(curCachedCfg) || (StringUtils.isEmpty(curCachedExecOrder) || !workOrder.getOrderNo().equals(curCachedExecOrder)))
                curCachedCfg = doCachedEsopCenterRemainCfg(organizeCode, workCenterCode);
            if (StringUtils.isEmpty(curCachedCfg) || StringUtils.isEmpty(curCachedExecOrder)) return doCachedOrderByEsopCenter(organizeCode, workCenterCode, workOrder.getOrderNo());
            if (MathOperation.compareTo(MathOperation.sub(workOrder.getQty(), workOrder.getCompleteQty()), new Double(curCachedCfg)) > 0) {
                if (!curCachedExecOrder.equals(workOrder.getOrderNo())) return doCachedOrderByEsopCenter(organizeCode, workCenterCode, workOrder.getOrderNo());
                else return curCachedExecOrder;
            } else {
                String firstOrder = getFirstOrder(organizeCode, workCenterCode, workOrder.getOrderNo());
                if (!StringUtils.isEmpty(firstOrder)) {
                    if (!curCachedExecOrder.equals(firstOrder)) return doCachedOrderByEsopCenter(organizeCode, workCenterCode, firstOrder);
                    else return curCachedExecOrder;
                } else {
                    if (!curCachedExecOrder.equals(workOrder.getOrderNo())) return doCachedOrderByEsopCenter(organizeCode, workCenterCode, workOrder.getOrderNo());
                    else return curCachedExecOrder;
                }
            }
        } catch (Exception e) {
            log.info("工厂{}生产线{}缓存作业指导书执行的生产工单出现异常:{}", organizeCode, workCenterCode, e.getMessage());
            return null;
        }
    }

    @Override
    public String doCachedOrderByEsopCenter(String organizeCode, String workCenterCode, String workOrderNo) {
        redisMesPcn.putHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_EXEC_ORDER, workOrderNo, MesEnumUtil.EXPIRE_TIME.NEVER.getValue());
        log.info("工厂{}生产线{}缓存作业指导书执行的生产工单{}成功", organizeCode, workCenterCode, workOrderNo);
        return workOrderNo;
    }

    @Override
    public String getCachedOrderByEsopCenter(String organizeCode, String workCenterCode) {
        return (String) redisMesPcn.getHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_EXEC_ORDER);
    }

    @Override
    public String getCachedReadRecordByEsopCenter(String organizeCode, String workCenterCode) {
        return (String) redisMesPcn.getHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_READ_RECORD);
    }

    @Override
    public void doCachedReadRecordByEsopCenter(String organizeCode, String workCenterCode, String workOrderNo) {
        redisMesPcn.putHash(getEsopCenterRemainKey(organizeCode, workCenterCode), MesPcnExtConstWords.ESOP_CENTER_READ_RECORD, workOrderNo, MesEnumUtil.EXPIRE_TIME.NEVER.getValue());
    }

    private String getFirstOrder(String organizeCode, String workCenterCode, String workOrderNo) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getStringNoEqualPack(workOrderNo, MesPcnExtConstWords.ORDER_NO, packBean);
        DdlPreparedPack.getNumEqualPack(MesPcnExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue(), MesPcnExtConstWords.WORK_ORDER_STATUS, packBean);
        DdlPreparedPack.getOrderByPack(new Object[]{CommonEnumUtil.ASC_OR_DESC.ASC.getValue()}, new String[]{MesPcnExtConstWords.SEQ}, packBean);
        MesWorkOrder workOrderDb = workOrderRepository.getByProperty(packBean);
        return null != workOrderDb ? workOrderDb.getOrderNo() : null;
    }

    private String getEsopCenterRemainKey(String organizeCode, String workCenterCode) {
        return new StringJoiner(MesPcnExtConstWords.COLON).add(organizeCode).add(MesPcnExtConstWords.ESOP_CENTER_REMAIN_DATA).add(workCenterCode).toString();
    }
}
