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

import cn.estsh.i3plus.ext.mes.pcn.api.base.ISxWorkOrderExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IProduceSnExtService;
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.util.MesPcnExtConstWords;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtEnumUtil;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.IShippingDispatchService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseModuleService;
import cn.estsh.i3plus.mes.pcn.util.PojoAttrUtil;
import cn.estsh.i3plus.platform.common.util.MesPcnConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
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.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.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;

/**
 * @Description : 展示组件：嘉兴条码下线
 * @Reference :
 * @Author :wangjie
 * @CreateDate : 2020-06-26 11:18 上午
 * @Modify:
 **/
@Slf4j
@Service("jxSnLineOffModuleService")
public class JxSnLineOffModuleService extends BaseModuleService {

    @Autowired
    private ISxWorkOrderExtService workOrderExtService;

    @Autowired
    private IProduceSnExtService produceSnExtService;

    @Autowired
    private IJxProduceSnExtService jxProduceSnExtService;

    @Autowired
    private IShippingDispatchService shippingDispatchService;

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

    @Override
    public void init(StationRequestBean reqBean) {
        MesWorkOrderExt workOrderExt = getCurExecWorkOrder(reqBean);
        doLoadData(reqBean, workOrderExt);
    }

    @Override
    public boolean execStateModule(StationRequestBean reqBean, List<MesStateMachineStatus> states, Map<String, String> wcpcMap) {
        String curExecWorkOrder = (String) doHandleCurExecWorkOrder(reqBean, 1, null);
        if (StringUtils.isEmpty(curExecWorkOrder)) return true;
        MesWorkOrderExt workOrderExtDb = getCachedWorkOrder(reqBean, curExecWorkOrder);
        if (null == workOrderExtDb) return true;
        doLoadData(reqBean, workOrderExtDb);
        return true;
    }

    private MesWorkOrderExt getCurExecWorkOrder(StationRequestBean reqBean) {
        String curExecWorkOrder = (String) doHandleCurExecWorkOrder(reqBean, 1, null);
        MesWorkOrderExt workOrderExtDb = StringUtils.isEmpty(curExecWorkOrder) ? null : getCachedWorkOrder(reqBean, curExecWorkOrder);
        return workOrderExtDb;
    }

    private String getDataKey(StationRequestBean reqBean) {
        return new StringJoiner(MesPcnExtConstWords.COLON).add(reqBean.getOrganizeCode())
                .add(MesPcnExtConstWords.JX_SN_LINE_OFF_DATA).add(reqBean.getWorkCenterCode()).add(reqBean.getWorkCellCode()).toString();
    }

    private MesWorkOrderExt getCachedWorkOrder(StationRequestBean reqBean, String curExecWorkOrder) {
        return workOrderExtService.getWorkOrderExtByOrderNo(reqBean.getOrganizeCode(), curExecWorkOrder);
    }

    private List<AttrBean> packDataAttrList() {
        List<AttrBean> attrBeanList = new ArrayList<>();
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.INDEX, "序号");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.MANAGE_CODE, "(源)管理码");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.STATUS_NAME, "下线状态");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.QC_STATUS_NAME, "产品状态");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.SERIAL_NUMBER, "过程条码");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.PRODUCT_SN, "产品条码");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.MODIFY_DATE_TIME, "操作时间");
        PojoAttrUtil.loadPojoAttrs(attrBeanList, MesPcnExtConstWords.MODIFY_USER, "操作人");
        return attrBeanList;
    }

    private void doLoadData(StationRequestBean reqBean, MesWorkOrderExt workOrderExt) {
        StationResultBean resultBean = new StationResultBean();

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

        if (null != workOrderExt) {
            List<MesProduceSnExt> produceSnList;
            if (MesPcnExtEnumUtil.WORK_ORDER_TYPE.REWORK_ORDER.getValue() != workOrderExt.getWorkOrderType())
                produceSnList = produceSnExtService.getProduceSnExtListByOrderNo(reqBean.getOrganizeCode(), workOrderExt.getOrderNo());
            else
                produceSnList = produceSnExtService.getProduceSnExtListByLastOrderNo(reqBean.getOrganizeCode(), workOrderExt.getOrderNo());

            List<String> processCodeList = jxProduceSnExtService.getBiggerCurProcessList(reqBean);

            resultBean.setResultMap(jxProduceSnExtService.packSnWorkCellScanResultMap(workOrderExt, jxProduceSnExtService.getSnCompleteQtyByProcessList(produceSnList, processCodeList)));

            resultBean.setResultList(jxProduceSnExtService.packSnWorkCellScanListByProcessList(produceSnList, processCodeList));
        }

        this.sendMessage(reqBean, resultBean);

    }

    @Override
    public boolean doFunction(StationRequestBean reqBean) {
        Boolean result = false;
        Map<String, Object> dataMap = reqBean.getDataMap();
        String command = (String) dataMap.get(MesPcnExtConstWords.COMMAND);
        Object value = dataMap.get(MesPcnExtConstWords.VALUE);
        if (StringUtils.isEmpty(command)) {
            this.sendMessage(reqBean,  null, "后端未获取到业务功能指令!", MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
            return result;
        }

        switch (command) {
            case MesPcnExtConstWords.CMD_WORK_ORDER :
                if (StringUtils.isEmpty(value)) {
                    this.sendMessage(reqBean,  null, "请选择启动状态的生产工单!", MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }

                String selectWorkOrderNo = (String) doHandleSelectWorkOrderNo(reqBean, 1, null);
                if (!StringUtils.isEmpty(selectWorkOrderNo) && selectWorkOrderNo.equals(value)) return result;
                reqBean.setForceJumpProcess(true);
                if (StringUtils.isEmpty(selectWorkOrderNo)) {
                    if ((Boolean) doHandleSelectWorkOrderNo(reqBean, 2, value.toString())) result = true;
                    else {
                        this.sendMessage(reqBean,  null, String.format("切换的生产工单[%s]缓存失败,请重试!", value), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                        return result;
                    }
                }
                break;
            case MesPcnExtConstWords.CMD_FORCE_CENTER_PASS :
                if (StringUtils.isEmpty(value)) {
                    this.sendMessage(reqBean,  null, "入参缺少产线强制放行的工步代码!", MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                String pwd = (String) dataMap.get(MesPcnExtConstWords.PWD);
                if (!jxProduceSnExtService.checkPorceCenterPassPwd(reqBean, pwd)) {
                    this.sendMessage(reqBean,  null, String.format("产线强制放行验证密码[%s]不正确!", pwd), MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
                    return result;
                }
                reqBean.setForceSpecStepCode(value.toString());
                result = true;
                break;
            default:
                break;
        }

        if (!result) this.sendMessage(reqBean,  null, "操作太频繁!", MesPcnEnumUtil.STATION_BUSI_TYPE.MESSAGE, MesPcnEnumUtil.STATION_DATA_TYPE.EXP_TEXT);
        else {
            //跳过工序
            reqBean.setClientInfo(shippingDispatchService.getActorClientInfo(reqBean));
            reqBean.setInterfaceType(MesPcnConstWords.SHIPPING);
            reqBean.setBusiType(MesPcnConstWords.WS_CMD_DO_SCAN);
            shippingDispatchService.doSendScanQueueNextExec(reqBean);
        }
        return result;
    }

    public synchronized Object doHandleCurExecWorkOrder(StationRequestBean reqBean, Integer flag, String curExecWorkOrder) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), MesPcnExtConstWords.CUR_EXEC_WORK_ORDER);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), MesPcnExtConstWords.CUR_EXEC_WORK_ORDER, curExecWorkOrder, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), MesPcnExtConstWords.CUR_EXEC_WORK_ORDER);
                return true;
            default:
                return null;
        }
    }

    public synchronized Object doHandleSelectWorkOrderNo(StationRequestBean reqBean, Integer flag, String selectWorkOrderNo) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), MesPcnExtConstWords.CMD_WORK_ORDER);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), MesPcnExtConstWords.CMD_WORK_ORDER, selectWorkOrderNo, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), MesPcnExtConstWords.CMD_WORK_ORDER);
                return true;
            default:
                return null;
        }
    }

    public Object doHandleBindKeyPartData(StationRequestBean reqBean, Integer flag, String item, String data) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), item);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), item, data, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                String[] itemArr = item.split(MesPcnExtConstWords.COMMA);
                for (String s : itemArr) {
                    redisMesPcn.deleteHash(getDataKey(reqBean), s);
                }
                return true;
            default:
                return null;
        }
    }

    public Object doHandlePlcData(StationRequestBean reqBean, String item, Integer flag, String plcData) {
        switch (flag) {
            case 1:
                return redisMesPcn.getHash(getDataKey(reqBean), item);
            case 2:
                return redisMesPcn.putHash(getDataKey(reqBean), item, plcData, MesPcnEnumUtil.EXPIRE_TIME.NEVER.getValue());
            case 3:
                redisMesPcn.deleteHash(getDataKey(reqBean), item);
                return true;
            default:
                return null;
        }
    }

}
