package cn.iocoder.yudao.module.system.mq.consumer.map;

import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseTakePointSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseTakePointDO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.remote.RemoteControllerInformationDO;
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
import cn.iocoder.yudao.module.system.enums.map.PointTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.event.EventTypeEnum;
import cn.iocoder.yudao.module.system.mq.message.map.MapMessage;
import cn.iocoder.yudao.module.system.service.houselocation.WareHouseTakePointService;
import cn.iocoder.yudao.module.system.service.information.DeviceInformationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MapConsumer {

    @Resource
    private PathApi pathApi;

    @Resource
    private DeviceInformationService deviceInformationService;

    @Resource
    private WareHouseTakePointService houseTakePointService;

    @EventListener
    @Async
    public void onMessage(MapMessage message) {
        if (EventTypeEnum.MAP_UPDATE.getType().equals(message.getEventType())) {
            pathApi.pathInitData();
            Long mapId = Long.valueOf(message.getMessage());
            List<DeviceInformationDO> devices = deviceInformationService.getDeviceInfoBindByMapId(mapId);
            if (ObjectUtil.isEmpty(devices)) {
                return;
            }

            List<Long> takePointIds = new ArrayList<>();
            List<WareHouseTakePointDO> takePointDOS = new ArrayList<>();
            for (DeviceInformationDO device : devices) {
                if (!DeviceTypeEnum.FLIP.getType().equals(device.getDeviceType()) || ObjectUtil.isNotEmpty(device.getTakePointId())) {
                    continue;
                }

                takePointIds.add(device.getTakePointId());

            }
            houseTakePointService.setTakePointMapIdEmpty(mapId, takePointIds);

            if (ObjectUtil.isEmpty(takePointIds)) {
                return;
            }

            WareHouseTakePointSaveReqVO reqVO = new WareHouseTakePointSaveReqVO();
            reqVO.setIds(takePointIds);
            List<WareHouseTakePointDO> houseTakePointList = houseTakePointService.getHouseTakePointList(reqVO);

            Map<Long, WareHouseTakePointDO> pointMap = houseTakePointList.stream().collect(Collectors.toMap(WareHouseTakePointDO::getId, Function.identity()));

            for (DeviceInformationDO device : devices) {
                if (!DeviceTypeEnum.FLIP.getType().equals(device.getDeviceType()) || ObjectUtil.isEmpty(device.getTakePointId())) {
                    continue;
                }
                WareHouseTakePointDO wareHouseTakePointDO = pointMap.get(device.getId());
                wareHouseTakePointDO.setPositionMapId(mapId);
                wareHouseTakePointDO.setActualLocationX(device.getActualLocationX());
                wareHouseTakePointDO.setActualLocationY(device.getActualLocationY());
                takePointDOS.add(wareHouseTakePointDO);
            }
            houseTakePointService.updateBatchById(takePointDOS);
        }
    }


}
