package com.mushiny.wms.slam;

import com.mushiny.wms.application.business.common.RfidBusiness;
import com.mushiny.wms.application.config.RestTempConfig;
import com.mushiny.wms.application.domain.*;
import com.mushiny.wms.application.domain.enums.InstructStatus;
import com.mushiny.wms.application.domain.enums.TripState;
import com.mushiny.wms.application.domain.enums.TripType;
import com.mushiny.wms.application.rabbitMq.RabbitMessageSender;
import com.mushiny.wms.application.repository.*;
import com.mushiny.wms.common.utils.DateTimeUtil;
import com.mushiny.wms.common.utils.EntityManagerUtil;
import com.mushiny.wms.common.utils.JSONUtil;
import com.mushiny.wms.rfid.RFIDConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.Map;


/**
 * Slam任务执行服务
 */
@Service
@Transactional
public class SlamTripService {

    private static final Integer CODE_OK = 0;
    private String token;
    private final MapRepository mapRepository;

    public String getToken() {
        return token;
    }

    public void setToken(String token) {
        this.token = token;
    }

    private final WmsSlamTripRepository wmsSlamTripRepository;
    private final OutboundInstructRepository outboundInstructRepository;
    public static final Logger logger = LoggerFactory.getLogger(SlamTripService.class);

    @Value("${mushiny.midea.slam.url}")
    private String mideaUrl;

    @Value("${mushiny.midea.slam.url_select}")
    private String mideaUrl_select;

    @Value("${mushiny.midea.slam.appSecret}")
    private String appSecret;

    @Value("${mushiny.midea.slam.mes.callBack}")
    private String mesCallBackUrl;

    private final RestTemplateBuilder builder;

    private final EntityManagerUtil entityManagerUtil;
    private final RfidBusiness rfidBusiness;
    private final PodRepository podRepository;
    private final RabbitMessageSender sender;
    private final SectionRepository sectionRepository;
    private final TripRepository tripRepository;
    private final RestTempConfig restTempConfig;
    //private final RestTempConfig restTempConfig;
    private final MapNodeRepository mapNodeRepository;
    private final MdStationnodepositionRepository mdStationnodepositionRepository;

    public final WmsSlamCarRepository wmsSlamCarRepository;

    @Autowired
    public SlamTripService(MapRepository mapRepository, WmsSlamTripRepository wmsSlamTripRepository, OutboundInstructRepository outboundInstructRepository, RestTemplateBuilder builder, EntityManagerUtil entityManagerUtil, RfidBusiness rfidBusiness, PodRepository podRepository, RabbitMessageSender sender, SectionRepository sectionRepository, TripRepository tripRepository, RestTempConfig restTempConfig, MapNodeRepository mapNodeRepository, MdStationnodepositionRepository mdStationnodepositionRepository, WmsSlamCarRepository wmsSlamCarRepository) {
        this.mapRepository = mapRepository;
        this.wmsSlamTripRepository = wmsSlamTripRepository;
        this.outboundInstructRepository = outboundInstructRepository;
        this.builder = builder;
        this.entityManagerUtil = entityManagerUtil;
        this.rfidBusiness = rfidBusiness;
        this.podRepository = podRepository;
        this.sender = sender;
        this.sectionRepository = sectionRepository;
        this.tripRepository = tripRepository;
        //this.restTempConfig = restTempConfig;
        this.restTempConfig = restTempConfig;
        this.mapNodeRepository = mapNodeRepository;
        this.mdStationnodepositionRepository = mdStationnodepositionRepository;
        this.wmsSlamCarRepository = wmsSlamCarRepository;
    }

    public void execute() {
        if(this.getToken() == null){
            logger.error("Token未生成，等待下一次循环!");
            return;
        }
        RestTemplate restTemplate = builder.build();

        List<WmsSlamTrip> wmsSlamTrips = this.wmsSlamTripRepository.findAllAvailableTrip();
        logger.error("查询到 wmsSlamTrips:"+wmsSlamTrips.size());
        if(wmsSlamTrips!=null && !wmsSlamTrips.isEmpty()){
            for (int i = 0; i < wmsSlamTrips.size(); i++) {
                WmsSlamTrip wmsSlamTrip = wmsSlamTrips.get(i);
                logger.debug("准备执行:"+wmsSlamTrip);
                Map params = new HashMap();
                //String id = CommonUtils.genUUID();
                params.put("taskId", wmsSlamTrip.getId());
                params.put("areaCode",wmsSlamTrip.getAreaCode());
                params.put("warehouseCode",wmsSlamTrip.getWarehouseCode());
                params.put("taskType",wmsSlamTrip.getTaskType());
                params.put("startStationCode",wmsSlamTrip.getStartTag());
                //String instrutId = CommonUtils.parseString(MideaConstants.INSTRUCT,data);
                //String targetTag = this.getEndTag(instrutId);
                params.put("endStationCode", wmsSlamTrip.getEndTag());
                params.put("storageNo",wmsSlamTrip.getStorageNo());
                params.put("priority",wmsSlamTrip.getPriority());
                params.put("taskDateTime", wmsSlamTrip.getTaskDateTime()+".123");
                String timespan = System.currentTimeMillis()+"";
                String sign = this.exportSign(params,timespan);
                logger.debug("params:"+params);
                logger.debug("sign:"+sign);
                try {
                    HttpHeaders headers = new HttpHeaders();
                    headers.add("sign",sign.toLowerCase());
                    headers.add("ACCESS_TOKEN",this.getToken());
                    headers.add("timespan",timespan);
                    MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
                    headers.setContentType(type);
                    headers.add("Accept", MediaType.APPLICATION_JSON.toString());
                    HttpEntity<String> httpEntity = new HttpEntity<String>(JSONUtil.mapToJSon(params), headers);
                    ResponseEntity<String> responseEntity = restTemplate.postForEntity(this.mideaUrl, httpEntity, String.class);
                    logger.info("Slam服务器返回数据是:"+responseEntity.getBody());
                    this.updateState(responseEntity.getBody(),wmsSlamTrip);
                } catch (Exception e) {
                    logger.error("发送到激光AGV出错!", e);
                }

                logger.debug("执行完毕:"+wmsSlamTrip);
            }
        }
    }

    private void updateState(String body, WmsSlamTrip wmsSlamTrip) {
        Map dataRes = JSONUtil.jsonToMap(body);//TODO
        if(!Objects.equals(dataRes.get("code"), SlamTripService.CODE_OK)){
            logger.error("异常码非0,后台执行错误!");
            return;
        }
        Map data = (Map) dataRes.get("data");
        //String carNo = (String) data.get("CarNo");
        String state = CommonUtils.parseString("state",data);//(String) data.get("state");
        Integer iState = Integer.parseInt(state);
        String taskDateTime = (String) data.get("taskDateTime");
        wmsSlamTrip.setTripState(iState);
        wmsSlamTrip.setCarNo((String) data.get("carNo"));
        wmsSlamTrip.setTaskDateTime(taskDateTime);
        this.wmsSlamTripRepository.saveAndFlush(wmsSlamTrip);
        logger.info("更新Slam调度任务成功 ID:" + wmsSlamTrip.getId());
    }

    public String exportSign(Map params, String timespan) {
        logger.info("输入参数:"+params);
        List keys = new ArrayList();
        keys.addAll(params.keySet());
        Collections.sort(keys);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(this.appSecret).append(timespan);
        for (int i = 0; i < keys.size(); i++) {
            String key = (String) keys.get(i);
            stringBuilder.append(key).append(CommonUtils.parseString(key,params));
        }
        stringBuilder.append(timespan).append(this.appSecret);

        logger.debug("拼接后的字符串是:"+stringBuilder);
        String md5Str = CommonUtils.md5(stringBuilder.toString());
        logger.debug("MD5的字符串是:"+stringBuilder);
        return md5Str;
    }

    public void agvError(String agvErrorMsg) {
        logger.info("更新Slam调度任务:"+agvErrorMsg);
        Map data = JSONUtil.jsonToMap(agvErrorMsg);
        String carNo = CommonUtils.parseString("carNo",data);
        WmsSlamCar wmsSlamCar = this.wmsSlamCarRepository.findCar(carNo);
        if(wmsSlamCar == null){
            wmsSlamCar = new WmsSlamCar();
            wmsSlamCar.setId(CommonUtils.genUUID());
        }
        String errorCode = CommonUtils.parseString("carNo",data);
        String errorMsg = CommonUtils.parseString("errorMsg",data);
        String status = CommonUtils.parseString("status",data);
        String occurTime = CommonUtils.parseString("occurTime",data);

        wmsSlamCar.setCarNo(carNo);
        wmsSlamCar.setErrorCode(errorCode);
        wmsSlamCar.setErrorMsg(errorMsg);
        wmsSlamCar.setStatus(status);
        wmsSlamCar.setOccurTime(occurTime);
        this.wmsSlamCarRepository.saveAndFlush(wmsSlamCar);
    }

    /*"taskId": "任务标识，string (20)，必填 任务更新操作的主键", "areaCode": " 区 域 编 码 ，string (50)， 选 填 ", "warehouseCode": " 仓 库 编 码 ，string (50)， 选 填 ", "storageNo": "料架编码，string (50) ，必填 默认”0”", "carNo": "小车编码，string (50) ，必填 默认”0”",
"state": "任务状态，int ，必填 1-开始执行 10-到达起点  20-离开起点 30-到达终点"
"taskDateTime": "交互当前时间，string（23）， ‘yyyy-MM-DD HH:mm:ss.f ff’"*/

    public void agvTaskConfirm(String taskConfirm) {
        logger.info("更新Slam调度任务:"+taskConfirm);
        Map data = JSONUtil.jsonToMap(taskConfirm);
        String taskId = (String) data.get("taskId");
        WmsSlamTrip wmsSlamTrip = this.wmsSlamTripRepository.getOne(taskId);
        String state = CommonUtils.parseString("state",data);//(String) data.get("state");
        Integer iState = Integer.parseInt(state);
        String taskDateTime = (String) data.get("taskDateTime");
        wmsSlamTrip.setTripState(iState);
        wmsSlamTrip.setCarNo((String) data.get("carNo"));
        wmsSlamTrip.setTaskDateTime(taskDateTime);
        Pod pod = this.podRepository.getPodById(wmsSlamTrip.getStorageNo());
        if(Objects.equals(iState, WmsSlamTrip.LEAVING)
                && Objects.equals(wmsSlamTrip.getTaskType(), WmsSlamTrip.TASKTYPE_BACK)){
            //处理
            OutboundInstruct outboundInstruct = this.outboundInstructRepository.getInstruByInstructId(wmsSlamTrip.getInstructId());
            Map  param=new HashMap();
            //如果找不到指令 表示未MES直接下发的空货架回库操作 信息不全
            if (outboundInstruct!=null) {
                param.put("ID",outboundInstruct.getMES_ID());
                param.put("INV_ORG_ID",outboundInstruct.getINV_ORG_ID());
                param.put("BILL_TYPE",outboundInstruct.getBILL_TYPE());
                param.put("BILL_NO",outboundInstruct.getBILL_NO());
                param.put("LABEL_NO",outboundInstruct.getLABEL_NO());
                param.put("INV_CODE", outboundInstruct.getINV_CODE());
                param.put("STOCK_QTY",outboundInstruct.getQTY());
                param.put("LABEL_NO",outboundInstruct.getLABEL_NO());
                param.put("INV_CODE", outboundInstruct.getINV_CODE());
                param.put("STOCK_QTY",outboundInstruct.getQTY());
            } else {
                param.put("ID",wmsSlamTrip.getInstructId());//已置换成了新的ID
                param.put("INV_ORG_ID",wmsSlamTrip.getInvOrgId());
                param.put("BILL_TYPE",wmsSlamTrip.getBillType());
                //param.put("BILL_NO",wmsSlamTrip.getb());
            }

            param.put("STORAGE_NO_L",wmsSlamTrip.getStorageNo());
            param.put("CAR_NO", data.get("carNo"));
            param.put("LOC_CODE",wmsSlamTrip.getStartTag());//TODO
            param.put("DATETIME_STOCK",taskDateTime);
            param.put("STATUS", InstructStatus.CARBACK.getStatus());
            Map res = restTempConfig.outBoundAck(param);
            logger.error("返回值 res:"+res);
        }
        if(Objects.equals(iState, WmsSlamTrip.CARRYFINISH)
                && Objects.equals(wmsSlamTrip.getTaskType(), WmsSlamTrip.TASKTYPE_BACK)){
            //如果是入库 要发货架入场
            Integer placeMark = this.getAddrCodeByEndTag(wmsSlamTrip.getEndTag());
            if (placeMark!=null && placeMark!=0) {
                pod.setPlaceMark(placeMark);
                this.podRepository.saveAndFlush(pod);
                Map param=new HashMap();
                param.put("ID",pod.getId());
                param.put("NAME",pod.getName());
                param.put("TOWARD","0");
                param.put("SECTION_ID",pod.getSectionId());
                param.put("PLACEMARK",placeMark);
                Section section=this.sectionRepository.getOne(pod.getSectionId());
                sender.sendMessage(param,section.getName(), RFIDConstants.WMS_WCS_POD_ADD_REMOVE);
                //产生podRun任务 二维码货架入场
                //产生任务？
                List<String> tripStates = new ArrayList<>();
                tripStates.add(TripState.NEW.getName());
                tripStates.add(TripState.AVAILABLE.getName());
                //tripStates.add(TripState.PROCESS.getName());
                //tripStates.add(TripState.LEAVING.getName());
                List<Trip> trips = this.tripRepository.getTripsByPodId(tripStates,pod.getId(),pod.getSectionId());
                if (trips == null || trips.isEmpty()) {
                    Trip trip = new Trip();
                    trip.setTripType(TripType.POD_RUN.getName());
                    trip.setTripState(TripState.NEW.getName());
                    trip.setPodId(pod.getId());
                    //trip.setInstruct(instructDefault);
                    //trip.setWorkStationId(stationId);
                    //trip.setMdNodePosition(stationNodePositionId);
                    trip.setSectionId(pod.getSectionId());
                    trip.setWarehouseId(pod.getWarehouseId());
                    // 保存调度单
                    this.tripRepository.saveAndFlush(trip);
                }
            }
        }
        if(Objects.equals(iState, WmsSlamTrip.LEAVING)
                && Objects.equals(wmsSlamTrip.getTaskType(), WmsSlamTrip.TASKTYPE_OUT)){
            //如果是出库 要发货架出场&& Objects
            pod.setPlaceMark(0);
            this.podRepository.saveAndFlush(pod);
            this.rfidBusiness.inventoryReduction(pod);
        }
        //TODO 这个操作可能是BUG
        wmsSlamTrip.setTripState(Integer.valueOf(state));
        //wmsSlamTrip.setTripState(WmsSlamTrip.EMPTYPODIN);
        this.wmsSlamTripRepository.saveAndFlush(wmsSlamTrip);
        logger.info("更新Slam调度任务成功 ID:" + taskId);
    }

    private String postData(Map map, String mesCallBackUrl) {
        RestTemplate restTemplate = this.builder.build();
        HttpHeaders headers = new HttpHeaders();
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(type);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> httpEntity = new HttpEntity<String>(JSONUtil.mapToJSon(map), headers);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(mesCallBackUrl, httpEntity, String.class);
        logger.info("Slam服务器返回数据是:"+responseEntity.getBody());
        return responseEntity.getBody();
    }

    public static final String SQL_FINDADDRCODEBYENDTAG = "SELECT WD_NODE.* FROM WD_NODE,WMS_SLAM_NODE " +
            "WHERE WMS_SLAM_NODE.NODEID=WD_NODE.ID AND WMS_SLAM_NODE.SLAM_NODE=:endTag";
    private Integer getAddrCodeByEndTag(String endTag) {
        Map data = new HashMap();
        data.put("endTag",endTag);
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery(SQL_FINDADDRCODEBYENDTAG,data);
        if(nodes==null || nodes.isEmpty()){
            logger.error("endTag:"+endTag+"未定义不存在:WMS_SLAM_NODE");
            return 0;
        }
        Map map = nodes.get(0);
        return (Integer) map.get("ADDRESSCODEID");
    }

    public String agvTaskSelect(String taskId) {
        RestTemplate restTemplate = builder.build();
        //WmsSlamTrip wmsSlamTrip = this.wmsSlamTripRepository.getOne(taskId);
        //String areaCode = wmsSlamTrip.getAreaCode();

        Map params = new HashMap();
        //params.put("areaCode",areaCode);
        params.put("taskId",taskId);
        //todo url key
        String timespan = System.currentTimeMillis()+"";
        String sign = this.exportSign(params, timespan);

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.add("sign",sign.toLowerCase());
            headers.add("ACCESS_TOKEN",this.getToken());
            headers.add("timespan",timespan);
            MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(type);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            //headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            //headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            HttpEntity<String> httpEntity = new HttpEntity<String>(JSONUtil.mapToJSon(params), headers);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(this.mideaUrl_select, httpEntity, String.class);
            logger.info("Slam服务器返回数据是:"+responseEntity.getBody());
            return responseEntity.getBody();
        } catch (Exception e) {
            logger.error("调用激光AGV出错!",e);
            return e.getMessage();
        }
    }
    public static final String SQL = "SELECT SLAM_NODE FROM WMS_SLAM_NODE WHERE SLAM_NODENAME=:tagName";
    public String agvTaskFinish(String tagName, String mesId) {
        OutboundInstruct instuct = this.outboundInstructRepository.getInstruById(mesId);
        //tagName --> slam_node
        Map data = new HashMap();
        data.put("tagName",tagName);
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery(SQL,data);
        if(nodes==null || nodes.isEmpty()){
            return "tagName:"+tagName+"未定义不存在:WMS_SLAM_NODE";
        }
        Map map = nodes.get(0);
        String slamNode = (String) map.get("SLAM_NODE");
        WmsSlamTrip wmsSlamTrip = this.wmsSlamTripRepository.findTripByInstructAndEndTag(instuct.getId(),slamNode);
        wmsSlamTrip.setTripState(WmsSlamTrip.FINISHTASK);
        this.wmsSlamTripRepository.saveAndFlush(wmsSlamTrip);
        return wmsSlamTrip.toString();
    }
    public static final String SQL_SLAM_POD_IN = "SELECT WMS_SLAM_NODE.NODEID,WMS_SLAM_NODE.SLAM_NODE FROM MD_STATIONNODEPOSITION, MD_STATIONNODE ,WD_NODE,WMS_SLAM_NODE\n" +
            "WHERE MD_STATIONNODE.ID=MD_STATIONNODEPOSITION.STATIONNODE_ID AND MD_STATIONNODE.TYPE=6 AND WMS_SLAM_NODE.NODEID=MD_STATIONNODEPOSITION.NODE_ID\n" +
            "AND WD_NODE.ID=MD_STATIONNODEPOSITION.NODE_ID AND WD_NODE.ADDRESSCODEID \n" +
            "NOT IN(SELECT PLACEMARK FROM MD_POD WHERE MD_POD.SECTION_ID='ec229eb7-7e2b-43a8-b1c7-91bd807e91cf')";
    public void buildSlamEmptyPodInTrip() {
        List<WmsSlamTrip> wmsSlamTrip = this.wmsSlamTripRepository.findAllEmptyPod();
        //查找可用于激光AGV入库的点位
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery(SQL_SLAM_POD_IN,new HashMap<>());
        if(nodes == null || nodes.isEmpty()){
            logger.error("没有找到SLAM回库配置的接驳位!");
            return;
        }
        for (int i = 0; i < wmsSlamTrip.size()&& i < nodes.size(); i++) {
            WmsSlamTrip slamTrip = wmsSlamTrip.get(i);
            Map node = nodes.get(i);
            //生成回库的SLAM调度任务
            WmsSlamTrip slamTripBack = new WmsSlamTrip();
            slamTripBack.setStorageNo(slamTrip.getStorageNo());
            slamTripBack.setStartTag(slamTrip.getEndTag());
            slamTripBack.setEndTag((String) node.get("SLAM_NODE"));
            slamTripBack.setStorageNo(slamTrip.getStorageNo());
            slamTripBack.setTripState(WmsSlamTrip.AVAILABLE);
            slamTripBack.setPriority(99);//默认
            slamTripBack.setInstructId(slamTrip.getInstructId());//相同
            slamTripBack.setInvOrgId(slamTrip.getInvOrgId());//默认
            slamTripBack.setBillType(slamTrip.getBillType());//默认
            slamTripBack.setTaskType(WmsSlamTrip.TASKTYPE_BACK);//回库
            slamTripBack.setWarehouseCode(slamTrip.getWarehouseCode());//回库
            slamTripBack.setAreaCode(slamTrip.getAreaCode());//回库

            //任务状态
            slamTrip.setTripState(WmsSlamTrip.EMPTYPODIN);
            this.wmsSlamTripRepository.saveAndFlush(slamTrip);
            this.wmsSlamTripRepository.saveAndFlush(slamTripBack);
            logger.debug("slamTrip"+slamTrip);
            logger.debug("slamTripBack"+slamTripBack);
        }
    }
    /*bill_type="CARBACK"，是新任务触发给到WMS，后面再回传给MES；
      bill_type="LMGETMATERIAL",是旧任务，WMS主动回传空车状态给MES更新旧任务的状态*/
    public static final String CARBACK = "CARBACK";
    public static final String LMGETMATERIAL = "LMGETMATERIAL";
    public synchronized String emptyPodBack(String workcenterCode, String mesId, String billType, String invOrgId, MushinyMessage mm) {
        /*OutboundInstruct instuct = this.outboundInstructRepository.getInstruById(mesId);
        if(instuct == null){
            mm.setCode("0");
            mm.setMessage("mesId:"+mesId+" 指令不存在!");
            return "mesId:"+mesId+" 指令不存在!";
        }*/
        //tagName --> slam_node
        mm.setCode("1");
        Map data = new HashMap();
        data.put("tagName",workcenterCode);
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery(SQL,data);
        if(nodes==null || nodes.isEmpty()){
            mm.setCode("0");
            mm.setMessage("tagName:"+workcenterCode+"未定义不存在:WMS_SLAM_NODE");
            return "tagName:"+workcenterCode+"未定义不存在:WMS_SLAM_NODE";
        }
        Map map = nodes.get(0);
        String slamNode = (String) map.get("SLAM_NODE");
        List<WmsSlamTrip> wmsSlamTrips = this.wmsSlamTripRepository.findTripByEndTag(slamNode);
        if(wmsSlamTrips == null || wmsSlamTrips.isEmpty()){
            mm.setCode("0");
            mm.setMessage("tagName:"+workcenterCode+"不存在已完成搬运 状态为5的SLAM调度任务");
            return "tagName:"+workcenterCode+"不存在已完成搬运 状态为5的SLAM调度任务";
        }
        if(wmsSlamTrips.size()>1){
            mm.setCode("0");
            mm.setMessage("tagName:"+workcenterCode+"存在多条已完成搬运 状态为5的SLAM调度任务");
            return "tagName:"+workcenterCode+"存在多条已完成搬运 状态为5的SLAM调度任务";
        }
        WmsSlamTrip wmsSlamTrip = wmsSlamTrips.get(0);
        wmsSlamTrip.setTripState(WmsSlamTrip.FINISHTASK);
        /*wmsSlamTrip.setBillType(billType);
        wmsSlamTrip.setInvOrgId(invOrgId);
        if (CARBACK.equals(billType)) {
            wmsSlamTrip.setInstructId(mesId);//更改了指令？
        }*/
        this.wmsSlamTripRepository.saveAndFlush(wmsSlamTrip);
        mm.setMessage(wmsSlamTrip.toString());
        mm.setCode("1");
        return wmsSlamTrip.toString();
    }
    public static final String SECTIONID = "ec229eb7-7e2b-43a8-b1c7-91bd807e91cf";
    public static final String MAPID = "8a55cdc8-dd5c-4a07-87e7-3979511949de";
    public String slamPodOut(String podId, String mesId) {
        //根据货架查找目的地
        Pod pod = this.podRepository.getByPodIndex(Integer.parseInt(podId),SECTIONID);
        if(pod == null || pod.getPlaceMark() == null || pod.getPlaceMark() == 0){
            return "没有这个货架"+podId+" 或者货架没有地址";
        }
        Integer placeMark = pod.getPlaceMark();
        MapNode mapNode = this.mapNodeRepository.getByMapIdAndAddressCodeId(MAPID,placeMark);
        if(mapNode == null){
            return "货架的位置再地图上不存在:"+placeMark;
        }
        List<MdStationnodeposition> mdStationnodepositions = this.mdStationnodepositionRepository.getAllSlamInterNodes();
        if(mdStationnodepositions == null){
            return "没有找到出库配置的节点";
        }
        Boolean contains = false;
        for (int i = 0; i < mdStationnodepositions.size(); i++) {
            MdStationnodeposition mdStationnodeposition = mdStationnodepositions.get(i);
            if(Objects.equals(mdStationnodeposition.getNode().getId(),mapNode.getId())){
                contains = true;
                break;
            }
        }
        if(!contains){
            return "货架不在SLAM出库位置,请检查数据库配置!";
        }
        String startTag = this.node2SlamTag(mapNode.getId());
        //获取终点
        OutboundInstruct outboundInstruct = this.outboundInstructRepository.getInstruById(mesId);
        String endTag = this.getEndTag(outboundInstruct);

        WmsSlamTrip wmsSlamTrip = new WmsSlamTrip();
        wmsSlamTrip.setId(CommonUtils.genUUID());
        wmsSlamTrip.setAreaCode("NANSHA");
        wmsSlamTrip.setWarehouseCode("NANSHA");
        wmsSlamTrip.setTaskType(WmsSlamTrip.TASKTYPE_OUT);
        wmsSlamTrip.setStartTag(startTag);
        wmsSlamTrip.setEndTag(endTag);
        wmsSlamTrip.setPriority(99);
        wmsSlamTrip.setStorageNo(pod.getId());
        wmsSlamTrip.setTaskDateTime(DateTimeUtil.getNowFormat("yyyy-MM-DD HH:mm:ss"));//todo
        wmsSlamTrip.setTripState(WmsSlamTrip.AVAILABLE);
        //增加billType inv_org_id
        wmsSlamTrip.setBillType(outboundInstruct.getBILL_TYPE());
        wmsSlamTrip.setInvOrgId(outboundInstruct.getINV_ORG_ID());
        wmsSlamTrip.setInstructId(outboundInstruct.getId());//TODO
        //this.wmsSlamTripRepository.save(wmsSlamTrip);
        this.wmsSlamTripRepository.saveAndFlush(wmsSlamTrip);
        logger.info("生成SLAM的调度任务，WMS_SLAM_TRIP:" + wmsSlamTrip.getId());

        return "wmsSlamTrip"+wmsSlamTrip;
    }
    //拷贝的代码
    private static final String sql2 = "SELECT * FROM WMS_SLAM_NODE WHERE NODEID=:nodeId";

    private String node2SlamTag(String endTag) {
        if(CommonUtils.isEmpty(endTag)){
            logger.error("地址码是空" + endTag);
            return null;
        }
        Map param = new HashMap();
        param.put("nodeId", endTag);

        List<Map> nodes = this.entityManagerUtil.executeNativeQuery2(sql2, param);
        if (nodes != null && !nodes.isEmpty()) {
            Map data = nodes.get(0);
            return (String) data.get("SLAM_NODE");
        }
        return null;
    }

    private static final String sql3 = "SELECT SLAM_NODE FROM WMS_SLAM_NODE WHERE SLAM_NODENAME=:workcenterCode";

    private String getEndTag(OutboundInstruct instrutId) {
        String workcenterCode = instrutId.getWORKCENTER_CODE();

        Map param = new HashMap();
        param.put("workcenterCode", workcenterCode);
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery2(sql3, param);
        if (nodes != null && !nodes.isEmpty()) {
            Map data = nodes.get(0);
            return (String) data.get("SLAM_NODE");
        }
        return null;
    }
    //拷贝的代码

    public String slamPodIn(String podId, String mesId) {
        //根据货架查找目的地
        //根据货架查找目的地
        Pod pod = this.podRepository.getByPodIndex(Integer.parseInt(podId),SECTIONID);
        if(pod == null || (pod.getPlaceMark() != null && pod.getPlaceMark() != 0)){
            return "没有这个货架"+podId+" 或者货架记录在仓库内，不在仓库外";
        }
        //获取终点
        OutboundInstruct outboundInstruct = this.outboundInstructRepository.getInstruById(mesId);
        //查找货架在SLAM的位置 只可能存在6个工作站点位
        WmsSlamTrip slamTrip = this.wmsSlamTripRepository.findPodNode(pod.getId(), outboundInstruct.getId());
        if(slamTrip == null){
            return "Pod:"+podId+" mesId:"+mesId+" 没有SLAM出库任务，无法下发回库任务";
        }

        //查找可用于激光AGV入库的点位
        List<Map> nodes = this.entityManagerUtil.executeNativeQuery(SQL_SLAM_POD_IN,new HashMap<>());
        if(nodes == null || nodes.isEmpty()){
            logger.error("没有找到SLAM回库配置的接驳位!");
            return "没有找到SLAM回库配置的接驳位!";
        }
        Map node = nodes.get(0);
        WmsSlamTrip slamTripBack = new WmsSlamTrip();
        slamTripBack.setStorageNo(slamTrip.getStorageNo());
        slamTripBack.setStartTag(slamTrip.getEndTag());
        slamTripBack.setEndTag((String) node.get("SLAM_NODE"));
        slamTripBack.setStorageNo(slamTrip.getStorageNo());
        slamTripBack.setTripState(WmsSlamTrip.AVAILABLE);
        slamTripBack.setPriority(99);//默认
        slamTripBack.setInstructId(slamTrip.getInstructId());//相同
        slamTripBack.setInvOrgId(slamTrip.getInvOrgId());//默认
        slamTripBack.setBillType(slamTrip.getBillType());//
        slamTripBack.setTaskType(WmsSlamTrip.TASKTYPE_BACK);//
        slamTripBack.setWarehouseCode(slamTrip.getWarehouseCode());//
        slamTripBack.setAreaCode(slamTrip.getAreaCode());//

        //TODO 不改变状态
        this.wmsSlamTripRepository.saveAndFlush(slamTripBack);
        logger.info("生成SLAM的调度任务，WMS_SLAM_TRIP:" + slamTripBack.getId());

        return "wmsSlamTrip"+slamTripBack;

    }



    public void buildPodOutTrip() {
        List<MdStationnodeposition> stationnodes =
                this.mdStationnodepositionRepository.getSlamNodes(Stationnode.SLAMOUT);
        if(stationnodes == null || stationnodes.isEmpty()){
            logger.error("未定义SLAM出库接驳位!");
            return;
        }

        for (int i = 0; i < stationnodes.size(); i++) {
            MdStationnodeposition mdStationnodeposition = stationnodes.get(i);
            MapNode mapNode = mdStationnodeposition.getNode();
            com.mushiny.wms.application.domain.Map map = this.mapRepository.findOne(mapNode.getMapId());
            Section section = this.sectionRepository.getOne(map.getSectionId());
            List<Pod> pods = this.podRepository.getByAddressCodeId(mapNode.getAddressCodeId(),section.getId());
            if(pods == null || pods.isEmpty()){
                logger.error("出库位:"+mapNode.getAddressCodeId()+"没有货架");
                continue;
            }
            Pod pod = pods.get(0);
            //检查货架是否有正在执行的SLAM出库指令 生成SLAM调度任务
            /*Trip trip = this.tripRepository.getLastPodTrip()
            OutboundInstruct outboundInstruct = this.outbound*/
        }
    }

    public void buildPodInTrip() {
        List<MdStationnodeposition> stationnodes =
                this.mdStationnodepositionRepository.getSlamNodes(Stationnode.SLAMIN);;
        if(stationnodes == null || stationnodes.isEmpty()){
            logger.error("未定义SLAM入库接驳位!");
            return;
        }
        //检查是否有货架，如果有 生成podrun

    }
}
