package com.ruoyi.web.controller.mqtt;

import com.ruoyi.common.model.MqttMessage;
import com.ruoyi.mqtt.service.MqttService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * MQTT控制器
 *
 * <p>提供MQTT相关操作的REST API接口，包括消息发布、主题订阅和连接管理等，
 * 方便通过HTTP请求操作MQTT客户端。</p>
 *
 * @author andy
 * @version 1.0.0
 * @since 2025-06-17
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/mqtt")
public class MqttController {

    private final MqttService mqttService;

    /**
     * 获取MQTT连接状态
     *
     * @return 连接状态信息
     */
    @GetMapping("/status")
    public ResponseEntity<Map<String, Object>> getStatus() {
        Map<String, Object> status = new HashMap<>();
        status.put("connected", mqttService.isConnected());
        status.put("timestamp", System.currentTimeMillis());

        return ResponseEntity.ok(status);
    }

    /**
     * 重新连接MQTT服务器
     *
     * @return 重连结果
     */
    @RequestMapping("/reconnect")
    public ResponseEntity<Map<String, Object>> reconnect() {
        Map<String, Object> result = new HashMap<>();

        try {
            CompletableFuture<Void> future = mqttService.reconnect();
            future.get(10, TimeUnit.SECONDS);

            result.put("success", true);
            result.put("message", "已成功重新连接到MQTT服务器");
            return ResponseEntity.ok(result);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            log.error("重连MQTT服务器失败: {}", e.getMessage(), e);

            result.put("success", false);
            result.put("message", "重连MQTT服务器失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }
    }

    /**
     * 发布MQTT消息
     *
     * @param message MQTT消息对象
     * @return 发布结果
     */
    @PostMapping("/publish")
    public ResponseEntity<Map<String, Object>> publishMessage(@RequestBody MqttMessage message) {
        Map<String, Object> result = new HashMap<>();

        if (message.getTopic() == null || message.getTopic().isEmpty()) {
            result.put("success", false);
            result.put("message", "消息主题不能为空");
            return ResponseEntity.badRequest().body(result);
        }

        if (message.getPayload() == null) {
            result.put("success", false);
            result.put("message", "消息内容不能为空");
            return ResponseEntity.badRequest().body(result);
        }

        try {
            CompletableFuture<Void> future = mqttService.publish(message);
            future.get(10, TimeUnit.SECONDS);

            result.put("success", true);
            result.put("message", "消息发布成功");
            result.put("topic", message.getTopic());
            return ResponseEntity.ok(result);
        } catch (InterruptedException | ExecutionException | TimeoutException e) {
            log.error("发布消息失败: {}", e.getMessage(), e);

            result.put("success", false);
            result.put("message", "发布消息失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }
    }

    /**
     * 简化版发布消息接口
     *
     * @param topic 消息主题
     * @param payload 消息内容
     * @return 发布结果
     */
    @RequestMapping("/publish/simple")
    public ResponseEntity<Map<String, Object>> publishSimpleMessage(
            @RequestParam String topic,
            @RequestParam String payload) {

        MqttMessage message = new MqttMessage(topic, payload);
        return publishMessage(message);
    }

    /**
     * 订阅主题
     *
     * @param topic 要订阅的主题
     * @return 订阅结果
     */
    @RequestMapping("/subscribe")
    public ResponseEntity<Map<String, Object>> subscribeTopic(@RequestParam String topic) {
        Map<String, Object> result = new HashMap<>();

        if (topic == null || topic.isEmpty()) {
            result.put("success", false);
            result.put("message", "订阅主题不能为空");
            return ResponseEntity.badRequest().body(result);
        }

        try {
            String subscribedTopic = mqttService.subscribe(topic);

            result.put("success", true);
            result.put("message", "主题订阅成功");
            result.put("topic", subscribedTopic);
            return ResponseEntity.ok(result);
        } catch (MqttException e) {
            log.error("订阅主题失败: {}", e.getMessage(), e);

            result.put("success", false);
            result.put("message", "订阅主题失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }
    }

    /**
     * 批量订阅主题
     *
     * @param topics 要订阅的主题列表
     * @return 订阅结果
     */
    @PostMapping("/subscribe/batch")
    public ResponseEntity<Map<String, Object>> subscribeTopics(@RequestBody List<String> topics) {
        Map<String, Object> result = new HashMap<>();

        if (topics == null || topics.isEmpty()) {
            result.put("success", false);
            result.put("message", "订阅主题列表不能为空");
            return ResponseEntity.badRequest().body(result);
        }

        try {
            List<String> subscribedTopics = mqttService.subscribe(topics);

            result.put("success", true);
            result.put("message", "批量主题订阅成功");
            result.put("topics", subscribedTopics);
            return ResponseEntity.ok(result);
        } catch (MqttException e) {
            log.error("批量订阅主题失败: {}", e.getMessage(), e);

            result.put("success", false);
            result.put("message", "批量订阅主题失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }
    }

    /**
     * 取消订阅主题
     *
     * @param topic 要取消订阅的主题
     * @return 取消订阅结果
     */
    @PostMapping("/unsubscribe")
    public ResponseEntity<Map<String, Object>> unsubscribeTopic(@RequestParam String topic) {
        Map<String, Object> result = new HashMap<>();

        if (topic == null || topic.isEmpty()) {
            result.put("success", false);
            result.put("message", "取消订阅的主题不能为空");
            return ResponseEntity.badRequest().body(result);
        }

        try {
            mqttService.unsubscribe(topic);

            result.put("success", true);
            result.put("message", "主题取消订阅成功");
            result.put("topic", topic);
            return ResponseEntity.ok(result);
        } catch (MqttException e) {
            log.error("取消订阅主题失败: {}", e.getMessage(), e);

            result.put("success", false);
            result.put("message", "取消订阅主题失败: " + e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
        }
    }
}
