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

import cn.estsh.i3plus.ext.mes.pcn.api.busi.jx.IJxPlcExtService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.actor.shipping.dispatch.IFsmCommonService;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IModuleService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.base.BaseStepService;
import cn.estsh.i3plus.platform.common.util.MesPcnConstWords;
import cn.estsh.i3plus.pojo.mes.bean.MesPlc;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.StringJoiner;

/**
 * @Description : 嘉兴通知PLC放行工步
 * @Reference :
 * @Author : wangjie
 * @CreateDate : 2019-07-11
 * @Modify:
 **/
@Slf4j
@Service("jxCenterPlcPassStepService")
public class JxCenterPlcPassStepService extends BaseStepService {

    @Autowired
    private IFsmCommonService fsmCommonService;

    @Autowired
    private IJxPlcExtService plcExtService;

    @Override
    public StepResult execute(StationRequestBean reqBean) {

        log.info("工厂{}生产线{}工位{}: --- STEP EXECUTE --- JxCenterPlcPassStepService --- START --- ", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        StationResultBean resultBean = new StationResultBean();

        String forceCmdKey = new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.FORCE).add(reqBean.getStepCode()).toString();
        Boolean forceCmd = reqBean.getDataMap().containsKey(forceCmdKey);
        if (forceCmd) reqBean.getDataMap().remove(forceCmdKey);

        fsmCommonService.checkWcpcMapForDoScan(reqBean);

        String plcPassValueParamCode = reqBean.getDataMap().containsKey(MesPcnExtConstWords.PLC_PASS_VALUE) ? (String) reqBean.getDataMap().get(MesPcnExtConstWords.PLC_PASS_VALUE) : MesPcnExtConstWords.PLC_PASS_VALUE;
        String plcPassValue = fsmCommonService.getAndCheckWcpcMapIsContainsKey(reqBean, reqBean.getWcpcMap(), plcPassValueParamCode);
        if (StringUtils.isEmpty(plcPassValue)) foundExThrowNoShowMsg();

        if (!plcPassValue.equals("noplc")) {

            String plcCode = fsmCommonService.getAndCheckWcpcMapIsContainsKey(reqBean, reqBean.getWcpcMap(), MesPcnExtConstWords.PLC_CODE_UC);

            if (StringUtils.isEmpty(plcCode)) foundExThrowNoShowMsg();

            MesPlc plcDb = getPlcDb(reqBean, resultBean, plcCode);
            if (null == plcDb) execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("生产线[%s]工位[%s]工位参数[%s]值[%s]对应的PLC信息不存在!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), MesPcnExtConstWords.PLC_CODE_UC, plcCode));

            if (!plcExtService.doWriteOpcParamValue(plcDb, plcPassValue))
                execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("生产线[%s]工位[%s]%s放行失败:写入PLC[%s]值[%s]失败!", reqBean.getWorkCenterCode(), reqBean.getWorkCellCode(), !forceCmd ? MesPcnExtConstWords.EMPTY : "强制", plcCode, plcPassValue));

        }

        if (reqBean.getDataMap().containsKey(MesPcnExtConstWords.PLC_PASS_VALUE)) reqBean.getDataMap().remove(MesPcnExtConstWords.PLC_PASS_VALUE);

        log.info("工厂{}生产线{}工位{}: --- STEP EXECUTE --- JxCenterPlcPassStepService --- SUCCESS ---", reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), reqBean.getWorkCellCode());

        if (!forceCmd) return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean,
                String.format("%s产线放行成功!", StringUtils.isEmpty(reqBean.getProductSn()) ? String.format("管理编码[%s]", getManageCode(reqBean.getTray(), 1)) : String.format("产品条码[%s]", reqBean.getProductSn())));
        else return execSuccessCompleteAndSendMsgReturn(reqBean, resultBean, "产线强制放行成功!");
    }

    private MesPlc getPlcDb(StationRequestBean reqBean, StationResultBean resultBean, String plcCode) {
        String plcStr = (String) doHandlePlcData(reqBean, resultBean, plcCode, 1, null);
        MesPlc plcDb = !StringUtils.isEmpty(plcStr) ? JSONObject.parseObject(plcStr, MesPlc.class) : plcExtService.getPlcDb(reqBean.getOrganizeCode(), plcCode);
        if (StringUtils.isEmpty(plcStr) && null != plcDb) doHandlePlcData(reqBean, resultBean, plcCode, 2, JSONObject.toJSONString(plcDb));
        return plcDb;
    }

    private Object doHandlePlcData(StationRequestBean reqBean, StationResultBean resultBean, String plcCode, Integer flag, String value) {
        try {
            IModuleService moduleService = (IModuleService) SpringContextsUtil.getBean(reqBean.getWcpcMap().get(MesPcnConstWords.MODULE_OBJECT));
            Method method = moduleService.getClass().getDeclaredMethod(MesPcnExtConstWords.doHandlePlcData, reqBean.getClass(), String.class, Integer.class, String.class);
            method.setAccessible(true);
            return method.invoke(moduleService, reqBean, new StringJoiner(MesPcnExtConstWords.COLON).add(MesPcnExtConstWords.PLC_CODE_UC).add(plcCode).toString(), flag, value);
        } catch (Exception e) {
            execExpSendMsgAndThrowEx(reqBean, resultBean, String.format("执行展示组件内部方法[%s]参数[flag=%s,value=%s]出现异常:%s", MesPcnExtConstWords.doHandlePlcData, flag, value, e.getMessage()));
            return null;
        }
    }

    private String getManageCode(String manageCode, Integer length) {
        if (StringUtils.isEmpty(manageCode)) return null;
        String[] manageCodeArr = manageCode.split(MesPcnExtConstWords.AND);
        if (manageCodeArr.length >= length) return manageCodeArr[length - 1];
        else return null;
    }

}
