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

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesCellEquipContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionProcessContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesProductionPsOutContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.MesScanMonitorContext;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.ActorMessage;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesOrderModel;
import cn.estsh.i3plus.mes.pcn.config.SpringExtProvider;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
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.i3plus.pojo.mes.util.MesExtEnumUtil;
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.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Description : 保存工艺参数
 * @Author : zxw
 **/
@Slf4j
@Service("mesVariableWhenFinishedReadStepService")
public class MesVariableWhenFinishedReadStepService extends BaseStepService {

    @Autowired
    private ActorSystem actorSystem;

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesProductionDispatchContextStepService mesProductionDispatchContextStepService;

    private static final Map<String, ActorRef> refMap = new ConcurrentHashMap<>(200);

    /**
     * 工艺参数设计到的表记录可能会很庞大，会达到1w以上，如果此工步直接同步保存会影响整个效率
     * 1 获取生成的条码信息，记录中需要保存该数据
     * 2 通过Actor异步保存工艺参数，同时生成一条记录，以便于job保存加工工艺参数
     * @param reqBean
     * @return
     */
    @Override
    public StepResult execute(StationRequestBean reqBean) {

        StepResult stepResult = StepResult.getSuccessComplete();

        StationResultBean resultBean = new StationResultBean();

        // 获取上下文信息
        MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);

        //获取上下文工位扫描监控信息
        MesScanMonitorContext scanMonitorContext = productionProcessContextStepService.dispatchScanMonitorContext(reqBean, true);

        // 获取条码信息
        List<MesProductionPsOutContext> mesProduceSnContexts = mesProductionDispatchContextStepService.getProductionPsOutContext(reqBean);

        // 通过上下文获取工位设备信息
        MesCellEquipContext curCellEquip = productionProcessContext.getCurCellEquip();

        List<MesOrderModel> modelList = mesProduceSnContexts.stream().map(order ->
             MesOrderModel.builder().workOrderNo(order.getWorkOrderNo()).productSn(order.getProductSn()).partNo(order.getPartNo()).build()
        ).collect(Collectors.toList());

        String mesProduceSnsStr = !CollectionUtils.isEmpty(modelList) ? JSONObject.toJSONString(modelList) : null;
        ActorMessage actorMessage = ActorMessage.builder()
                .equipmentCode(curCellEquip.getEquipmentCode())
                .equipId(curCellEquip.getEquipId())
                .organizeCode(reqBean.getOrganizeCode())
                .organizeName(reqBean.getOrganizeName())
                .workCellCode(reqBean.getWorkCellCode())
                .workCenterCode(reqBean.getWorkCenterCode())
                .areaCode(reqBean.getAreaCode())
                .craftCode(productionProcessContext.getCraftCode())
                .processCode(reqBean.getProcessCode())
                .produceSnJson(mesProduceSnsStr)
                .userName(reqBean.getUserInfo())
                .mouldRecordId(scanMonitorContext.getMouldRecordId())
                .build();
        // 数据采集信息需要存放到 redis中

        // 需要保存磨具号

        String key = this.getFsmBusikey(reqBean, MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PROCESS_FINISH.name());
        ActorRef ref = refMap.computeIfAbsent(key,
                k -> actorSystem.actorOf(SpringExtProvider.getInstance().get(actorSystem).create("mesHandlerEquipLogActor"), key));
        ref.tell(actorMessage, ActorRef.noSender());

        return stepSuccessCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(MesPcnEnumUtil.WORK_CELL_SCAN_MONITOR_LOG_TYPE.PROCESS.getValue()), stepResult, "保存工艺参数成功!");
    }
}
