package com.mushiny.wms.rfid;

import com.mushiny.wms.application.business.common.RfidBusiness;
import com.mushiny.wms.application.domain.*;
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.CommonUtil;
import com.mushiny.wms.common.utils.JSONUtil;
import com.mushiny.wms.slam.CommonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.*;
import java.util.Map;

@Component
public class MideaRFIDService {
    public static final String InstructAck = "InstructAck";

    @Autowired
    private TripRepository tripRepository;

    @Autowired
    private PodRepository podRepository;
    @Autowired
    RabbitMessageSender sender;
    @Autowired
    private RfidBusiness rfidBusiness;

    @Autowired
    private OutboundInstructRepository outboundInstructRepository;

    @Autowired
    private RFIDWebApi rfidWebApi;

    private static final Logger LOGGER = LoggerFactory.getLogger(MideaRFIDService.class);
    @Autowired
    private SectionRepository sectionRepository;

    @Autowired
    private MdStationnodepositionRepository mdStationnodepositionRepository;


    /*入库时返回给RFID*/
    /*出库时返回给RFID*/
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "", durable = "true"),
            exchange = @Exchange(value = "${mushiny.section}" , ignoreDeclarationExceptions = "true"),
            key = InstructAck))
    public void InstructAck(Message message){
        /*ANNTOMVOUT和 LMLGETMATERIAL*/
        /*message.put("sectionID",section.getRcs_sectionId());
        message.put(MideaConstants.TRIP_ID,this.getOrderId());
        message.put(MideaConstants.TRIP_TYPE,this.getType());
        message.put(MideaConstants.TARGET_ADDRESS, this.getEndAddr());
        message.put(MideaConstants.DRIVE_ID, this.getRobot().getRobotId());
        message.put(MideaConstants.POD_INDEX,this.getPod().getPodId());
        message.put(MideaConstants.INSTRUCT_STATUS, MideaConstants.STOCKIN);
        MessageSender.sendMapMessage(message, MideaConstants.INSTRUCTACK);*/
        byte[] body = message.getBody();
        Map data = (Map) toObject(body);
        LOGGER.info("MideaRFIDService 收到消息 :"+data);
        String podId = CommonUtils.parseString(RFIDConstants.POD_INDEX,data);
        String addrCode = CommonUtils.parseString(RFIDConstants.TARGET_ADDRESS,data);//(String) data.get(RFIDConstants.TARGET_ADDRESS);
        String type = (String) data.get(RFIDConstants.TRIP_TYPE);
        String status = (String) data.get(RFIDConstants.INSTRUCT_STATUS);
        //出库的
        if (Objects.equals(RFIDConstants.STOCKOUT, status)
                && (Objects.equals(RFIDConstants.ANNTOMVOUT, type)
                || Objects.equals(RFIDConstants.LMGETMATERIAL, type))) {
            LOGGER.debug("发起出库申请到RFID:"+data);
            String tripId = (String) data.get(RFIDConstants.TRIP_ID);
            Trip trip = this.tripRepository.getTripByID(tripId);
            //String instruct = trip.getInstruct();
            Pod pod = this.podRepository.getPodById(podId);
            OutboundInstruct oi = outboundInstructRepository.getInstruByTripId(tripId);
            String res = rfidWebApi.podOutReq(pod.getPodIndex()+"", oi,pod.getPlaceMark()+"");
            LOGGER.debug("podOutReq返回信息====>"+res);
            return;
        }
        //入库的
        if (Objects.equals(RFIDConstants.RUNNING, status)
                && Objects.equals(RFIDConstants.PODRUN, type)) {
            LOGGER.debug("发起入库确认到RFID"+data);
            Pod pod = this.podRepository.getPodById(podId);
            //查找所有空车入库工作站的地址码
            List<MdStationnodeposition> pos
                    = this.mdStationnodepositionRepository.getStationPositionByType(3);
            boolean contains = false;
            for (int i = 0; i < pos.size(); i++) {
                MdStationnodeposition mdStationnodeposition = pos.get(i);
                if(mdStationnodeposition.getNode().getAddressCodeId() == pod.getPlaceMark()){
                    contains = true;
                    break;
                }
            }
            if(!contains){
                LOGGER.error("货架地址码非空货架入库工作站停止点:"+pod.getPlaceMark());
                return;
            }
            String res = rfidWebApi.podInConfirm(pod.getPodIndex()+"", pod.getPlaceMark()+"", RFIDConstants.ANNTOMVIN);
            LOGGER.debug("podInConfirm返回信息====>"+res);
            return;
        }
        LOGGER.info("MideaRFIDService 消息处理结束!");
    }

    /**
     * 数组转对象
     * @param bytes
     * @return
     */
    public static Object toObject (byte[] bytes) {
        Object obj = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream (bytes);
            ObjectInputStream ois = new ObjectInputStream (bis);
            obj = ois.readObject();
            ois.close();
            bis.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return obj;
    }
    @Transactional
    public String podOutConfirm(String podId, String addrCode) {
        //将系统货架更新成0号位置
        //往RCS下发指令
        LOGGER.debug("出库确认podOutConfirm podId:"+podId+" addrCode"+addrCode);
        Pod pod = this.podRepository.getByPodIndex2(Integer.parseInt(podId));
        pod.setPlaceMark(0);
        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",0);
        Section section=sectionRepository.getOne(pod.getSectionId());
        sender.sendMessage(param,section.getName(),RFIDConstants.WMS_WCS_POD_ADD_REMOVE);*/
        //库存减少？
        this.rfidBusiness.inventoryReduction(pod);
        Map res = new HashMap();
        res.put("code",0);
        res.put("msg","空料车出库请求处理成功!");
        LOGGER.debug("出库确认执行成功podOutConfirm podId:"+podId+" addrCode"+addrCode);
        return JSONUtil.mapToJSon(res);
    }

    public synchronized String podInReq(String podId, String addrCode) {
        LOGGER.debug("入库请求podInReq podId:"+podId+" addrCode"+addrCode);
        if(CommonUtil.isEmpty(addrCode) || Integer.parseInt(addrCode) == 0){
            Map res = new HashMap();
            res.put("code",1);
            res.put("msg","空料车入库请求处理失败! "+podId+" : "+addrCode);
            return JSONUtil.mapToJSon(res);
        }
        Pod pod = this.podRepository.getByPodIndex2(Integer.parseInt(podId));
        Integer placeMark = pod.getPlaceMark();
        if(pod.getPlaceMark()!=null
                && pod.getPlaceMark()!=0L
                && !Objects.equals(Integer.parseInt(addrCode),placeMark)){
            //货架在系统位置不为0时 且入库位置不等于货架当前位置
            LOGGER.error("无法执行RFID货架入场，货架信息在系统中有记录的位置，并且与RFID发送的位置不一致! placeMark"
                    +placeMark+" addrCode"+addrCode);
            Map res = new HashMap();
            res.put("code",1);
            res.put("msg","货架信息在系统中有记录的位置，并且与RFID发送的位置不一致! placeMark"
                    +placeMark+" addrCode"+addrCode);
            LOGGER.debug("入库请求执行完成podInReq podId:"+podId+" addrCode"+addrCode);
            return JSONUtil.mapToJSon(res);
        }
        pod.setPlaceMark(Integer.parseInt(addrCode));
        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",addrCode);
        Section section=sectionRepository.getOne(pod.getSectionId());
        sender.sendMessage(param,section.getName(),RFIDConstants.WMS_WCS_POD_ADD_REMOVE);
        List<String> states = new ArrayList<>();
        states.add(TripState.AVAILABLE.getName());
        states.add(TripState.PROCESS.getName());
        List<Trip> trips = this.tripRepository.getTripsByPodId(states, pod.getId(),pod.getSectionId());
        if(!trips.isEmpty()){
            Map res = new HashMap();
            res.put("code",1);
            res.put("msg","空料车入库已有任务存在或执行，请求处理失败! "+podId+" : "+addrCode);
            return JSONUtil.mapToJSon(res);
        }
        //库存减少？
        this.rfidBusiness.inventoryReduction(pod);
        //产生任务？
        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());
        // 保存调度单
        tripRepository.saveAndFlush(trip);

        Map res = new HashMap();
        res.put("code",0);
        res.put("msg","空料车入库请求处理成功!");

        return JSONUtil.mapToJSon(res);
    }
}
