package com.liquidnet.common.swagger.service;

import com.liquidnet.common.swagger.annotation.ApiLevel;
import com.liquidnet.common.swagger.dto.ApiLevelStatisticsDto;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 接口分级统计服务
 * 
 * @author system
 * @since 2024-10-29
 */
@Service
@Slf4j
public class ApiLevelStatisticsService {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Value("${liquidnet.info.context:unknown-service}")
    private String rawServiceName;
    
    /**
     * 获取处理后的服务名称（去掉前后斜杠）
     */
    private String getCleanServiceName() {
        if (rawServiceName == null || rawServiceName.trim().isEmpty()) {
            return "unknown-service";
        }
        
        String cleaned = rawServiceName.trim();
        // 去掉前面的斜杠
        if (cleaned.startsWith("/")) {
            cleaned = cleaned.substring(1);
        }
        // 去掉后面的斜杠
        if (cleaned.endsWith("/")) {
            cleaned = cleaned.substring(0, cleaned.length() - 1);
        }
        
        return cleaned.isEmpty() ? "unknown-service" : cleaned;
    }
    
    /**
     * 获取所有接口的分级统计信息
     */
    public ApiLevelStatisticsDto getApiLevelStatistics() {
        ApiLevelStatisticsDto statistics = new ApiLevelStatisticsDto();
        
        // 获取所有Controller
        Map<String, Object> controllers = applicationContext.getBeansWithAnnotation(RestController.class);
        controllers.putAll(applicationContext.getBeansWithAnnotation(Controller.class));
        
        List<ApiLevelStatisticsDto.ApiInfo> apiInfoList = new ArrayList<>();
        
        for (Map.Entry<String, Object> entry : controllers.entrySet()) {
            Object controller = entry.getValue();
            Class<?> controllerClass = controller.getClass();
            
            // 跳过代理类
            if (controllerClass.getName().contains("$$")) {
                controllerClass = controllerClass.getSuperclass();
            }
            
            // 过滤掉系统自带的Controller
            if (shouldSkipController(controllerClass)) {
                continue;
            }
            
            // 使用配置文件中的服务名称
            
            // 获取类级别的ApiLevel注解
            ApiLevel classApiLevel = controllerClass.getAnnotation(ApiLevel.class);
            
            // 遍历所有方法
            Method[] methods = controllerClass.getDeclaredMethods();
            for (Method method : methods) {
                if (isApiMethod(method)) {
                    ApiLevelStatisticsDto.ApiInfo apiInfo = buildApiInfo(method, controllerClass, getCleanServiceName(), classApiLevel);
                    if (apiInfo != null) {
                        apiInfoList.add(apiInfo);
                    }
                }
            }
        }
        
        statistics.setApiList(apiInfoList);
        statistics.setTotalCount(apiInfoList.size());
        statistics.setLevelStatistics(calculateLevelStatistics(apiInfoList));
        
        // 注意：对于单服务，serviceStatistics与levelStatistics内容相同
        // 保留serviceStatistics是为了API一致性和未来扩展性
        statistics.setServiceStatistics(calculateServiceStatistics(apiInfoList));
        
        return statistics;
    }
    
    /**
     * 判断是否应该跳过该Controller
     */
    private boolean shouldSkipController(Class<?> controllerClass) {
        String className = controllerClass.getName();
        String simpleName = controllerClass.getSimpleName();
        
        // 过滤掉系统自带的Controller
        return className.contains("ApiResourceController") ||
               className.contains("BasicErrorController") ||
               simpleName.equals("ApiResourceController") ||
               simpleName.equals("BasicErrorController") ||
               // 过滤掉接口分级统计相关的Controller
               simpleName.equals("ApiLevelStatisticsController") ||
               className.contains("com.liquidnet.common.swagger.controller") ||
               // 过滤掉Spring Boot Actuator相关的Controller
               className.contains("org.springframework.boot.actuate") ||
               // 过滤掉Spring Security相关的Controller
               className.contains("org.springframework.security") ||
               // 过滤掉其他框架的Controller
               className.contains("springfox.documentation") ||
               className.contains("com.github.xiaoymin.knife4j");
    }
    
    /**
     * 判断是否为API方法
     */
    private boolean isApiMethod(Method method) {
        return method.isAnnotationPresent(RequestMapping.class) ||
               method.isAnnotationPresent(GetMapping.class) ||
               method.isAnnotationPresent(PostMapping.class) ||
               method.isAnnotationPresent(PutMapping.class) ||
               method.isAnnotationPresent(DeleteMapping.class) ||
               method.isAnnotationPresent(PatchMapping.class);
    }
    
    /**
     * 构建API信息
     */
    private ApiLevelStatisticsDto.ApiInfo buildApiInfo(Method method, Class<?> controllerClass, 
                                                      String serviceName, ApiLevel classApiLevel) {
        ApiLevelStatisticsDto.ApiInfo apiInfo = new ApiLevelStatisticsDto.ApiInfo();
        
        // 获取方法级别的ApiLevel注解
        ApiLevel methodApiLevel = method.getAnnotation(ApiLevel.class);
        ApiLevel effectiveApiLevel = methodApiLevel != null ? methodApiLevel : classApiLevel;
        
        // 如果没有ApiLevel注解，使用L99表示未配置
        if (effectiveApiLevel == null) {
            ApiLevel.Level unconfiguredLevel = ApiLevel.Level.L99;
            apiInfo.setLevel(unconfiguredLevel);
            apiInfo.setDescription(unconfiguredLevel.getDesc()); // 使用枚举中的描述
        } else {
            // 所有配置的级别都是正常的分级
            apiInfo.setLevel(effectiveApiLevel.level());
            apiInfo.setDescription(effectiveApiLevel.description());
        }
        
        // 设置基本信息
        apiInfo.setServiceName(serviceName);
        apiInfo.setControllerName(controllerClass.getSimpleName());
        apiInfo.setMethodName(method.getName());
        apiInfo.setUrl(getApiUrl(method, controllerClass));
        apiInfo.setHttpMethod(getHttpMethod(method));
        
        // 获取API描述
        ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
        if (apiOperation != null) {
            apiInfo.setApiDescription(apiOperation.value());
        }
        
        return apiInfo;
    }
    

    
    /**
     * 获取API URL
     */
    private String getApiUrl(Method method, Class<?> controllerClass) {
        StringBuilder url = new StringBuilder();
        
        // 获取类级别的RequestMapping
        RequestMapping classMapping = controllerClass.getAnnotation(RequestMapping.class);
        if (classMapping != null && classMapping.value().length > 0) {
            url.append(classMapping.value()[0]);
        }
        
        // 获取方法级别的映射
        String methodPath = getMethodPath(method);
        if (methodPath != null && !methodPath.isEmpty()) {
            if (!url.toString().endsWith("/") && !methodPath.startsWith("/")) {
                url.append("/");
            }
            url.append(methodPath);
        }
        
        return url.toString();
    }
    
    /**
     * 获取方法路径
     */
    private String getMethodPath(Method method) {
        if (method.isAnnotationPresent(RequestMapping.class)) {
            RequestMapping mapping = method.getAnnotation(RequestMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        if (method.isAnnotationPresent(GetMapping.class)) {
            GetMapping mapping = method.getAnnotation(GetMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        if (method.isAnnotationPresent(PostMapping.class)) {
            PostMapping mapping = method.getAnnotation(PostMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        if (method.isAnnotationPresent(PutMapping.class)) {
            PutMapping mapping = method.getAnnotation(PutMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        if (method.isAnnotationPresent(DeleteMapping.class)) {
            DeleteMapping mapping = method.getAnnotation(DeleteMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        if (method.isAnnotationPresent(PatchMapping.class)) {
            PatchMapping mapping = method.getAnnotation(PatchMapping.class);
            return mapping.value().length > 0 ? mapping.value()[0] : "";
        }
        return "";
    }
    
    /**
     * 获取HTTP方法
     */
    private String getHttpMethod(Method method) {
        if (method.isAnnotationPresent(GetMapping.class)) return "GET";
        if (method.isAnnotationPresent(PostMapping.class)) return "POST";
        if (method.isAnnotationPresent(PutMapping.class)) return "PUT";
        if (method.isAnnotationPresent(DeleteMapping.class)) return "DELETE";
        if (method.isAnnotationPresent(PatchMapping.class)) return "PATCH";
        
        if (method.isAnnotationPresent(RequestMapping.class)) {
            RequestMapping mapping = method.getAnnotation(RequestMapping.class);
            if (mapping.method().length > 0) {
                return mapping.method()[0].name();
            }
        }
        return "GET";
    }
    
    /**
     * 计算级别统计
     */
    private Map<String, Integer> calculateLevelStatistics(List<ApiLevelStatisticsDto.ApiInfo> apiList) {
        // 统计实际数据，现在所有级别都在枚举中
        Map<String, Integer> actualStats = apiList.stream()
                .collect(Collectors.groupingBy(
                        api -> api.getLevel().name(),
                        Collectors.collectingAndThen(Collectors.counting(), Math::toIntExact)
                ));
        
        // 动态获取所有配置的级别，确保所有级别都显示
        Map<String, Integer> completeStats = new LinkedHashMap<>();
        
        // 遍历枚举中定义的所有级别（包括L99）
        for (ApiLevel.Level level : ApiLevel.Level.values()) {
            completeStats.put(level.name(), actualStats.getOrDefault(level.name(), 0));
        }
        
        return completeStats;
    }
    

    
    /**
     * 计算服务统计
     */
    private Map<String, Map<String, Integer>> calculateServiceStatistics(List<ApiLevelStatisticsDto.ApiInfo> apiList) {
        // 先按服务分组统计，现在所有级别都在枚举中
        Map<String, Map<String, Integer>> actualServiceStats = apiList.stream()
                .collect(Collectors.groupingBy(
                        ApiLevelStatisticsDto.ApiInfo::getServiceName,
                        Collectors.groupingBy(
                                api -> api.getLevel().name(),
                                Collectors.collectingAndThen(Collectors.counting(), Math::toIntExact)
                        )
                ));
        
        // 为每个服务补全所有级别（确保所有级别都显示，没有数据的显示0）
        Map<String, Map<String, Integer>> completeServiceStats = new LinkedHashMap<>();
        for (Map.Entry<String, Map<String, Integer>> entry : actualServiceStats.entrySet()) {
            String serviceName = entry.getKey();
            Map<String, Integer> serviceLevelStats = entry.getValue();
            
            Map<String, Integer> completeLevelStats = new LinkedHashMap<>();
            
            // 动态获取所有配置的级别（包括L99）
            for (ApiLevel.Level level : ApiLevel.Level.values()) {
                completeLevelStats.put(level.name(), serviceLevelStats.getOrDefault(level.name(), 0));
            }
            
            completeServiceStats.put(serviceName, completeLevelStats);
        }
        
        return completeServiceStats;
    }
}