package com.ruoyi.database.util;

import com.ruoyi.database.service.SimpleKafkaMessageService;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

@Component
public class HikKafkaConsumer implements CommandLineRunner {

    private static final Logger logger = LoggerFactory.getLogger(HikKafkaConsumer.class);

    private final AtomicBoolean running = new AtomicBoolean(true);
    private ExecutorService executorService;
    private KafkaConsumer<String, String> consumer;

    @Autowired
    private Properties kafkaConsumerProperties;

    @Autowired
    private SimpleKafkaMessageService simpleKafkaMessageService;

    private String topic = "topic_releaseRequest32856dSpuPV,topic_pass32856ik8M5V";



    private boolean autoStart = true;

    private int consumerThreads = 1;

    @Override
    public void run(String... args) throws Exception {
        if (autoStart) {
            startConsumer();
        }
    }

    /**
     * 启动消费者
     */
    public synchronized void startConsumer() {
        if (executorService != null && !executorService.isShutdown()) {
            logger.warn("消费者已经在运行");
            return;
        }

        try {
            // 创建消费者实例
            consumer = new KafkaConsumer<>(kafkaConsumerProperties);
            consumer.subscribe(Arrays.asList(topic.split(",")));

            executorService = Executors.newFixedThreadPool(consumerThreads);

            for (int i = 0; i < consumerThreads; i++) {
                final int threadId = i;
                executorService.submit(() -> consumeMessages(threadId));
            }

            logger.info("海康Kafka消费者启动成功");
            printStartupInfo();

        } catch (Exception e) {
            logger.error("启动Kafka消费者失败", e);
            System.err.println("❌ 启动Kafka消费者失败: " + e.getMessage());
        }
    }

    /**
     * 消费消息
     */
    private void consumeMessages(int threadId) {
        String threadName = "kafka-consumer-" + threadId;
        Thread.currentThread().setName(threadName);

        logger.info("消费者线程 {} 启动", threadName);

        while (running.get()) {
            try {
                ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(1000));

                if (records.isEmpty()) {
                    // 没有消息时稍微休眠，避免CPU空转
                    Thread.sleep(100);
                    continue;
                }

                for (ConsumerRecord<String, String> record : records) {
                    processRecord(record, threadId);
                }

                // 异步提交偏移量（如果开启了自动提交则不需要）
                // consumer.commitAsync();

            } catch (Exception e) {
                logger.error("消费者线程 {} 消费消息异常", threadName, e);

                // 发生异常时等待一段时间再重试
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }

        logger.info("消费者线程 {} 停止", threadName);
    }

    /**
     * 处理单条记录
     */
    private void processRecord(ConsumerRecord<String, String> record, int threadId) {
        try {
            // 格式化输出到控制台
            String consoleOutput = formatConsoleOutput(record, threadId);
            System.out.println(consoleOutput);

            // 记录到日志文件（INFO级别）
            logger.info("消费者线程 {} - 主题: {}, 分区: {}, 偏移量: {}, 键: {}, 值: {}",
                    threadId, record.topic(), record.partition(),
                    record.offset(), record.key(), record.value());

            // 如果需要，这里可以添加业务处理逻辑
            simpleKafkaMessageService.processKafkaMessage(record.topic(), record.value());
        } catch (Exception e) {
            logger.error("处理消息记录失败", e);
            System.err.println("处理消息失败: " + e.getMessage());
        }
    }

    /**
     * 格式化控制台输出
     */
    private String formatConsoleOutput(ConsumerRecord<String, String> record, int threadId) {
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        sb.append("╔══════════════════════════════════════════════════════════════════╗\n");
        sb.append(String.format("║ 【海康Kafka消息】线程: %-6d                                  ║\n", threadId));
        sb.append("╠══════════════════════════════════════════════════════════════════╣\n");
        sb.append(String.format("║ 主题     : %-50s ║\n", record.topic()));
        sb.append(String.format("║ 分区     : %-50d ║\n", record.partition()));
        sb.append(String.format("║ 偏移量   : %-50d ║\n", record.offset()));
        sb.append(String.format("║ 时间戳   : %-50s ║\n", new java.util.Date(record.timestamp())));
        sb.append(String.format("║ 键       : %-50s ║\n",
                record.key() != null ? record.key() : "null"));

        // 处理消息值，如果太长则截断
        String value = record.value();
        if (value.length() > 50) {
            value = value.substring(0, 47) + "...";
        }
        sb.append(String.format("║ 值       : %-50s ║\n", value));
        sb.append("╚══════════════════════════════════════════════════════════════════╝\n");

        return sb.toString();
    }

    /**
     * 打印启动信息
     */
    private void printStartupInfo() {
        String servers = kafkaConsumerProperties.getProperty("bootstrap.servers");
        String groupId = kafkaConsumerProperties.getProperty("group.id");
        String username = extractUsernameFromJaasConfig();

        String startupInfo = String.format(
                "\n" +
                        "██████╗ ███████╗██╗   ██╗███████╗██╗  ██╗    ██╗  ██╗██╗██╗  ██╗\n" +
                        "██╔══██╗██╔════╝██║   ██║██╔════╝██║ ██╔╝    ██║ ██╔╝██║██║ ██╔╝\n" +
                        "██████╔╝█████╗  ██║   ██║███████╗█████╔╝     █████╔╝ ██║█████╔╝ \n" +
                        "██╔══██╗██╔══╝  ╚██╗ ██╔╝╚════██║██╔═██╗     ██╔═██╗ ██║██╔═██╗ \n" +
                        "██║  ██║███████╗ ╚████╔╝ ███████║██║  ██╗    ██║  ██╗██║██║  ██╗\n" +
                        "╚═╝  ╚═╝╚══════╝  ╚═══╝  ╚══════╝╚═╝  ╚═╝    ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝\n" +
                        "\n" +
                        "════════════════════  Kafka消费者启动成功 ═════════════════════\n" +
                        "服务器地址 : %s\n" +
                        "消费主题   : %s\n" +
                        "消费者组   : %s\n" +
                        "认证用户   : %s\n" +
                        "认证机制   : SCRAM-SHA-256\n" +
                        "线程数量   : %d\n" +
                        "═══════════════════════════════════════════════════════════\n",
                servers, topic, groupId, username, consumerThreads
        );

        System.out.println(startupInfo);
        logger.info(startupInfo);
    }

    /**
     * 从JAAS配置中提取用户名
     */
    private String extractUsernameFromJaasConfig() {
        String jaasConfig = (String) kafkaConsumerProperties.get("sasl.jaas.config");
        if (jaasConfig != null) {
            // 从类似 "username=\"userxxxxx\"" 的字符串中提取用户名
            int start = jaasConfig.indexOf("username=\"");
            if (start != -1) {
                start += "username=\"".length();
                int end = jaasConfig.indexOf("\"", start);
                if (end != -1) {
                    return jaasConfig.substring(start, end);
                }
            }
        }
        return "未知";
    }

    /**
     * 停止消费者
     */
    public synchronized void stopConsumer() {
        running.set(false);

        if (executorService != null) {
            executorService.shutdown();
            logger.info("正在停止消费者线程池...");
        }

        if (consumer != null) {
            consumer.close();
            logger.info("Kafka消费者已关闭");
        }

        System.out.println("Kafka消费者已停止");
    }

    /**
     * 重新启动消费者
     */
    public void restartConsumer() {
        stopConsumer();
        running.set(true);
        try {
            Thread.sleep(2000); // 等待2秒再重启
            startConsumer();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /**
     * 测试消费一条消息（用于验证连接）
     */
    public void testConsumeOne() {
        try (KafkaConsumer<String, String> testConsumer = new KafkaConsumer<>(kafkaConsumerProperties)) {
            testConsumer.subscribe(Arrays.asList(topic.split(",")));

            ConsumerRecords<String, String> records = testConsumer.poll(Duration.ofMillis(5000));

            if (records.isEmpty()) {
                System.out.println("测试消费：未收到任何消息（可能没有新消息）");
            } else {
                System.out.println("测试消费：收到 " + records.count() + " 条消息");
                for (ConsumerRecord<String, String> record : records) {
                    System.out.println("主题: " + record.topic() + ", 值: " + record.value());
                }
            }
        } catch (Exception e) {
            System.err.println("测试消费失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}