package com.erp.common.nacos;

import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.nacos.api.naming.pojo.Instance;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * Nacos服务注册与发现工具类
 * 提供服务元数据管理、健康检查、实例查询等高级功能
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class NacosServiceUtil {

    private final DiscoveryClient discoveryClient;
    private final Optional<Registration> registration;
    private final NacosServiceManager nacosServiceManager;

    // ==============================================================
    // 1. 服务注册状态检查
    // ==============================================================

    /**
     * 检查当前服务是否已注册到Nacos
     */
    public boolean isRegistered() {
        return registration.isPresent();
    }

    /**
     * 获取当前服务实例ID
     */
    public String getInstanceId() {
        return registration.map(r -> r.getInstanceId()).orElse("unknown");
    }

    /**
     * 获取当前服务实例信息
     */
    public Map<String, String> getMetadata() {
        return registration.map(Registration::getMetadata).orElse(Map.of());
    }

    // ==============================================================
    // 2. 服务发现
    // ==============================================================

    /**
     * 根据服务名获取所有健康实例
     */
    public List<ServiceInstance> getHealthyInstances(String serviceName) {
        return discoveryClient.getInstances(serviceName).stream()
                .filter(this::isHealthyInstance)
                .toList();
    }

    /**
     * 根据服务名获取所有实例（包括不健康的）
     */
    public List<ServiceInstance> getAllInstances(String serviceName) {
        return discoveryClient.getInstances(serviceName);
    }

    /**
     * 检查目标服务是否可用（至少有一个健康实例）
     */
    public boolean isServiceAvailable(String serviceName) {
        return !getHealthyInstances(serviceName).isEmpty();
    }

    private boolean isHealthyInstance(ServiceInstance instance) {
        if (instance instanceof Instance nacosInstance) {
            return nacosInstance.isHealthy();
        }
        return true; // 非Nacos实例默认健康
    }

    // ==============================================================
    // 3. 服务元数据管理
    // ==============================================================

    /**
     * 更新当前服务实例元数据
     * 注意：需要Nacos 2.x客户端支持
     */
    public void updateMetadata(Map<String, String> metadata) {
        registration.ifPresent(r -> {
            log.info("更新服务元数据: service={}, metadata={}", r.getServiceId(), metadata);
            // 元数据通过配置文件更新后，Nacos客户端会自动同步
        });
    }

    /**
     * 获取指定服务的所有实例及其元数据
     */
    public void printServiceDetails(String serviceName) {
        List<ServiceInstance> instances = getAllInstances(serviceName);
        log.info("服务 [{}] 实例信息 (共{}个):", serviceName, instances.size());
        
        for (ServiceInstance instance : instances) {
            log.info("  - InstanceId: {}", instance.getInstanceId());
            log.info("    Host: {}:{}", instance.getHost(), instance.getPort());
            log.info("    Metadata: {}", instance.getMetadata());
            log.info("    Scheme: {}", instance.getScheme());
        }
    }

    // ==============================================================
    // 4. 健康检查相关
    // ==============================================================

    /**
     * 发送自定义心跳（用于临时实例或特殊保活需求）
     */
    public void sendHeartbeat(String serviceName, String ip, int port) {
        log.debug("发送心跳: service={}, ip={}, port={}", serviceName, ip, port);
        // Nacos客户端自动发送心跳，通常不需要手动调用
        // 此方法用于理解心跳机制
    }

    /**
     * 获取Nacos客户端版本
     */
    public String getNacosClientVersion() {
        return nacosServiceManager.getNacosClientProperties().getProperty("nacos.client.version", "unknown");
    }
}
