package com.njzscloud.supervisory.device.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.mqtt.support.MqttMsg;
import com.njzscloud.common.mqtt.util.Mqtt;
import com.njzscloud.supervisory.biz.service.TruckLocationTrackService;
import com.njzscloud.supervisory.device.mapper.DeviceLocalizerMapper;
import com.njzscloud.supervisory.device.pojo.entity.DeviceLocalizerEntity;
import com.njzscloud.supervisory.device.pojo.result.DeviceInfoResult;
import com.njzscloud.supervisory.device.pojo.result.HeartbeatResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 定位器
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DeviceLocalizerService extends ServiceImpl<DeviceLocalizerMapper, DeviceLocalizerEntity> implements IService<DeviceLocalizerEntity> {
    private final TruckLocationTrackService truckLocationTrackService;

    /**
     * 新增
     */
    public void add(DeviceLocalizerEntity deviceLocalizerEntity) {
        this.save(deviceLocalizerEntity);
    }

    /**
     * 修改
     */
    public void modify(DeviceLocalizerEntity deviceLocalizerEntity) {
        this.updateById(deviceLocalizerEntity);
    }

    /**
     * 删除
     */
    @Transactional(rollbackFor = Exception.class)
    public void del(List<Long> ids) {
        this.removeBatchByIds(ids);
    }

    /**
     * 详情
     */
    public DeviceLocalizerEntity detail(Long id) {
        return this.getById(id);
    }

    /**
     * 分页查询
     */
    public PageResult<DeviceLocalizerEntity> paging(PageParam pageParam, DeviceLocalizerEntity deviceLocalizerEntity) {
        return PageResult.of(this.page(pageParam.toPage(), Wrappers.<DeviceLocalizerEntity>query(deviceLocalizerEntity)));
    }

    @EventListener(ApplicationReadyEvent.class)
    public void onApplicationReady() {
        List<DeviceLocalizerEntity> localizerEntities = this.list();
        List<String> collect = localizerEntities.stream().map(DeviceLocalizerEntity::getTerminalId).distinct().collect(Collectors.toList());
        for (String terminalId : collect) {
            Mqtt.subscribe(terminalId + "/online", this::heartbeat);
            Mqtt.subscribe(terminalId + "/device_info", this::updateDeviceLocalizerStatus);
            Mqtt.subscribe(terminalId + "/track_location_real", truckLocationTrackService::sendRealTimeData);
        }
    }

    public void heartbeat(MqttMsg msg) {
        HeartbeatResult heartbeatResult = msg.getMsg(HeartbeatResult.class);
        if (heartbeatResult == null) return;
        this.update(Wrappers.lambdaUpdate(DeviceLocalizerEntity.class)
                .set(DeviceLocalizerEntity::getOnline, heartbeatResult.isOnline())
                .set(DeviceLocalizerEntity::getLastTime, heartbeatResult.getTime())
                .eq(DeviceLocalizerEntity::getTerminalId, heartbeatResult.getTerminalId()));
    }

    public void updateDeviceLocalizerStatus(MqttMsg msg) {
        DeviceInfoResult deviceInfoResult = msg.getMsg(DeviceInfoResult.class);
        if (deviceInfoResult == null) return;
        this.update(Wrappers.lambdaUpdate(DeviceLocalizerEntity.class)
                .set(DeviceLocalizerEntity::getOnline, Boolean.TRUE)
                .set(DeviceLocalizerEntity::getLastTime, LocalDateTime.now())
                .eq(DeviceLocalizerEntity::getTerminalId, deviceInfoResult.getTerminalId()));
    }


}
