package com.seer.teach.user.admin.service.impl;

import com.alibaba.nacos.api.config.ConfigService;
import com.seer.teach.user.admin.service.ContextPathResolver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

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

@Slf4j
@Service
public class SmartContextPathResolver implements ContextPathResolver {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired(required = false)
    private ConfigService nacosConfigService;

    @Autowired
    private RestTemplate restTemplate;

    private final Map<String, String> contextPathCache = new ConcurrentHashMap<>();

    @Override
    public String resolveContextPath(String serviceName) {
        // 1. 检查缓存
        if (contextPathCache.containsKey(serviceName)) {
            return contextPathCache.get(serviceName);
        }

        // 2. 尝试从服务实例元数据获取
        String contextPath = getFromMetadata(serviceName);
        if (StringUtils.hasText(contextPath)) {
            cacheContextPath(serviceName, contextPath);
            return contextPath;
        }

        // 3. 尝试从配置中心获取
        contextPath = getFromConfigCenter(serviceName);
        if (StringUtils.hasText(contextPath)) {
            cacheContextPath(serviceName, contextPath);
            return contextPath;
        }

        // 4. 约定服务名就是上下文根，如seer-user,则是/seer/user
        contextPath = getFromServiceName(serviceName);
        if (StringUtils.hasText(contextPath)) {
            cacheContextPath(serviceName, contextPath);
            return contextPath;
        }

        // 5. 使用默认值
        log.warn("无法确定服务 {} 的上下文根，使用默认值", serviceName);
        cacheContextPath(serviceName, "");
        return "";
    }

    private String getFromMetadata(String serviceName) {
        try {
            List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
            if (!instances.isEmpty()) {
                return instances.get(0).getMetadata().getOrDefault("context-path", "");
            }
        } catch (Exception e) {
            log.warn("从元数据获取服务 {} 上下文根失败", serviceName, e);
        }
        return "";
    }

    private String getFromConfigCenter(String serviceName) {
        if (nacosConfigService == null) return "";

        try {
            String[] configKeys = {
                    serviceName + ".context-path",
                    serviceName + ".contextPath",
                    "services." + serviceName + ".context-path"
            };
            for (String key : configKeys) {
                String config = nacosConfigService.getConfig(key, "DEFAULT_GROUP", 3000);
                if (StringUtils.hasText(config)) {
                    return config.trim();
                }
            }
        } catch (Exception e) {
            log.warn("从配置中心获取服务 {} 上下文根失败", serviceName, e);
        }
        return "";
    }

    private String getFromServiceName(String serviceName) {
        try {
            String[] split = serviceName.split("-");
            if (split.length > 1){
                return "/" + split[0] + "/" + split[1];
            }
            return "/" + serviceName;
        } catch (Exception e) {
            log.warn("调用服务 {} 信息端点失败", serviceName, e);
        }
        return "";
    }

    private void cacheContextPath(String serviceName, String contextPath) {
        contextPathCache.put(serviceName, contextPath);
    }
}
