package com.erp.common.nacos;

import com.alibaba.nacos.api.annotation.NacosProperties;
import com.alibaba.nacos.api.common.pojo.Instance;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
import org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistration;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Nacos健康检查配置
 * 
 * Nacos 2.x 支持多种健康检查类型:
 * 1. TCP - 检测端口是否可连接
 * 2. HTTP - 发送HTTP请求检测
 * 3. MYSQL - 检测MySQL连接
 * 4. NONE - 不健康不摘除
 * 
 * 默认使用Spring Boot Actuator的/health端点作为健康检查
 */
@Slf4j
@Component("nacosHealthIndicator")
public class NacosHealthCheckConfig implements HealthIndicator {

    private final NacosDiscoveryProperties nacosDiscoveryProperties;
    
    @Value("${spring.application.name:unknown}")
    private String serviceName;

    // 存储服务状态（实际生产中由Nacos服务端维护）
    private static final Map<String, Boolean> SERVICE_HEALTH_STATUS = new ConcurrentHashMap<>();

    public NacosHealthCheckConfig(NacosDiscoveryProperties nacosDiscoveryProperties) {
        this.nacosDiscoveryProperties = nacosDiscoveryProperties;
    }

    @Override
    public Health health() {
        // 1. 检查Nacos连接
        if (!isNacosReachable()) {
            return Health.down()
                    .withDetail("nacos", "无法连接到Nacos服务器")
                    .build();
        }

        // 2. 检查实例是否已注册
        if (!isInstanceRegistered()) {
            return Health.down()
                    .withDetail("registration", "实例未注册到Nacos")
                    .build();
        }

        // 3. 检查本地健康状态
        if (!isLocalHealthy()) {
            return Health.down()
                    .withDetail("local", "本地健康检查失败")
                    .build();
        }

        // 4. 获取实例元数据
        Map<String, String> metadata = nacosDiscoveryProperties.getInstanceMetadataMap();

        return Health.up()
                .withDetail("service", serviceName)
                .withDetail("instanceId", nacosDiscoveryProperties.getInstanceId())
                .withDetail("namespace", nacosDiscoveryProperties.getNamespace())
                .withDetail("group", nacosDiscoveryProperties.getGroup())
                .withDetail("metadata", metadata)
                .withDetail("nacos", "连接正常")
                .build();
    }

    private boolean isNacosReachable() {
        try {
            // 简单连通性检查
            return true; // 实际生产中应该尝试连接
        } catch (Exception e) {
            log.error("Nacos连接检查失败", e);
            return false;
        }
    }

    private boolean isInstanceRegistered() {
        return nacosDiscoveryProperties.getInstanceId() != null;
    }

    private boolean isLocalHealthy() {
        // 这里可以添加自定义健康检查逻辑
        // 例如：检查数据库连接、Redis连接、MQ连接等
        return SERVICE_HEALTH_STATUS.getOrDefault(serviceName, true);
    }

    /**
     * 更新服务健康状态（可被外部调用）
     */
    public void setHealthy(String serviceName, boolean healthy) {
        SERVICE_HEALTH_STATUS.put(serviceName, healthy);
        log.info("更新服务健康状态: service={}, healthy={}", serviceName, healthy);
    }

    /**
     * 获取当前服务的所有实例健康状态
     */
    public void logAllInstancesHealth() {
        log.info("========== 服务实例健康状态 ==========");
        log.info("服务: {}", serviceName);
        log.info("命名空间: {}", nacosDiscoveryProperties.getNamespace());
        log.info("分组: {}", nacosDiscoveryProperties.getGroup());
        log.info("实例ID: {}", nacosDiscoveryProperties.getInstanceId());
        log.info("实例IP: {}", nacosDiscoveryProperties.getIp());
        log.info("实例端口: {}", nacosDiscoveryProperties.getPort());
        log.info("元数据: {}", nacosDiscoveryProperties.getInstanceMetadataMap());
        log.info("========================================");
    }
}
