package com.njzscloud.common.localizer.mqtt;

import cn.hutool.core.collection.CollUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.njzscloud.common.localizer.DeviceStore;
import com.njzscloud.common.localizer.Localizer;
import com.njzscloud.common.localizer.contant.LocalizerType;
import com.njzscloud.common.localizer.htzj.Htzj;
import com.njzscloud.common.localizer.mqtt.param.*;
import com.njzscloud.common.localizer.tuqiang.Tuqiang;
import com.njzscloud.common.mqtt.support.MqttListener;
import com.njzscloud.common.mqtt.support.MqttMsg;
import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class MqttMsgHandlers {

    TypeReference<List<DeviceLoadParam>> typeReference = new TypeReference<List<DeviceLoadParam>>() {
    };

    /**
     * 开启追踪
     */
    @MqttListener(topic = "location/track")
    public void onMessage(MqttMsg msg) {
        LocationTrackParam locationTrackParam = msg.getMsg(LocationTrackParam.class);
        String terminalId = locationTrackParam.getTerminalId();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.track(terminalId, locationTrackParam.getInterval());
                break;
            case HangTianZiJin:
                Htzj.track(terminalId, locationTrackParam.getInterval());
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 获取当前位置
     */
    @MqttListener(topic = "location/current")
    public void currentLocation(MqttMsg msg) {
        LocationCurrentParam locationCurrentParam = msg.getMsg(LocationCurrentParam.class);
        String terminalId = locationCurrentParam.getTerminalId();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.currentLocation(terminalId);
                break;
            case HangTianZiJin:
                Htzj.currentLocation(terminalId);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 启用报警
     */
    @MqttListener(topic = "location/warn")
    public void enableWarn(MqttMsg msg) {
        EnableWarnParam enableWarnParam = msg.getMsg(EnableWarnParam.class);
        String terminalId = enableWarnParam.getTerminalId();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        boolean enable = enableWarnParam.isEnable();
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.enableWarn(terminalId, enable);
                break;
            case HangTianZiJin:
                Htzj.enableWarn(terminalId, enable);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 配置设备的连接地址
     */
    @MqttListener(topic = "location/config_ip_port")
    public void configIpPort(MqttMsg msg) {
        ConfigIpPortParam configIpPortParam = msg.getMsg(ConfigIpPortParam.class);
        String terminalId = configIpPortParam.getTerminalId();
        String ip = configIpPortParam.getIp();
        int port = configIpPortParam.getPort();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.configIpPort(terminalId, ip, port);
                break;
            case HangTianZiJin:
                Htzj.configIpPort(terminalId, ip, port);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 设置速度阈值
     */
    @MqttListener(topic = "location/speed_threshold")
    public void speedThreshold(MqttMsg msg) {
        SpeedThresholdParam speedThresholdParam = msg.getMsg(SpeedThresholdParam.class);
        String terminalId = speedThresholdParam.getTerminalId();
        int speed = speedThresholdParam.getSpeed();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.speedThreshold(terminalId, speed);
                break;
            case HangTianZiJin:
                Htzj.speedThreshold(terminalId, speed);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 获取设备信息
     */
    @MqttListener(topic = "location/device_info")
    public void obtainDeviceInfo(MqttMsg msg) {
        ObtainDeviceInfoParam obtainDeviceInfoParam = msg.getMsg(ObtainDeviceInfoParam.class);
        String terminalId = obtainDeviceInfoParam.getTerminalId();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.obtainDeviceInfo(terminalId);
                break;
            case HangTianZiJin:
                Htzj.obtainDeviceInfo(terminalId);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }

    /**
     * 加载已注册的设备
     */
    @MqttListener(topic = "location/load")
    public void load(MqttMsg msg) {
        List<DeviceLoadParam> deviceLoadParams = msg.getMsg(typeReference.getType());
        if (CollUtil.isEmpty(deviceLoadParams)) {
            log.warn("未收到定位器加载参数");
            return;
        }
        LinkedList<Localizer> list = deviceLoadParams.stream()
                .map(it -> new Localizer()
                        .setTerminalId(it.getTerminalId())
                        .setSpeedThreshold(it.getSpeedThreshold())
                        .setLocalizerType(it.getLocalizerType()))
                .collect(Collectors.toCollection(LinkedList::new));
        DeviceStore.setLocalizers(list);
    }

    /**
     * 发送指令
     */
    @MqttListener(topic = "localizer/send_directive")
    public void sendDirective(MqttMsg msg) {
        SendDirectiveParam sendDirectiveParam = msg.getMsg(SendDirectiveParam.class);
        String terminalId = sendDirectiveParam.getTerminalId();
        LocalizerType localizerType = DeviceStore.determineType(terminalId);
        if (localizerType == null) {
            log.warn("未确定定位器类型，终端ID：{}", terminalId);
            return;
        }
        String directive = sendDirectiveParam.getDirective();
        switch (localizerType) {
            case Tuqiang:
                Tuqiang.sendDirective(terminalId, directive);
                break;
            case HangTianZiJin:
                Htzj.sendDirective(terminalId, directive);
                break;
            default:
                log.warn("不支持的定位器类型：{}", localizerType);
        }
    }
}
