package com.ruoyi.credit.monitor;

import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.ruoyi.common.utils.DateUtils;

/**
 * 验证性能监控器
 * 添加验证过程的性能监控
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Component
public class ValidationPerformanceMonitor {

    private static final Logger log = LoggerFactory.getLogger(ValidationPerformanceMonitor.class);

    /** 验证超时阈值（毫秒） */
    @Value("${loan.validation.rules.timeout:30000}")
    private long validationTimeoutThreshold;

    /** 性能警告阈值（毫秒） */
    @Value("${loan.validation.performance.warningThreshold:2000}")
    private long performanceWarningThreshold;

    /** 高负载检测阈值 */
    @Value("${loan.validation.performance.highLoadThreshold:80}")
    private int highLoadThreshold;

    /** 性能统计数据 */
    private final Map<String, PerformanceMetrics> metricsMap = new ConcurrentHashMap<>();

    /** 当前活跃验证任务数 */
    private final AtomicInteger activeValidationTasks = new AtomicInteger(0);

    /** 总验证次数 */
    private final AtomicLong totalValidations = new AtomicLong(0);

    /** 超时验证次数 */
    private final AtomicLong timeoutValidations = new AtomicLong(0);

    /** 性能警告次数 */
    private final AtomicLong performanceWarnings = new AtomicLong(0);

    /**
     * 开始验证性能监控
     * 
     * @param loanId 贷款ID
     * @param validationType 验证类型
     * @return 性能监控上下文
     */
    public PerformanceContext startValidationMonitoring(Long loanId, String validationType) {
        log.debug("开始验证性能监控，贷款ID: {}, 验证类型: {}", loanId, validationType);
        
        activeValidationTasks.incrementAndGet();
        totalValidations.incrementAndGet();
        
        PerformanceContext context = new PerformanceContext(loanId, validationType);
        context.setStartTime(System.currentTimeMillis());
        
        // 检查当前系统负载
        checkSystemLoad(context);
        
        return context;
    }

    /**
     * 结束验证性能监控
     * 
     * @param context 性能监控上下文
     * @param success 验证是否成功
     */
    public void endValidationMonitoring(PerformanceContext context, boolean success) {
        if (context == null) {
            return;
        }

        long endTime = System.currentTimeMillis();
        long executionTime = endTime - context.getStartTime();
        context.setEndTime(endTime);
        context.setExecutionTime(executionTime);
        context.setSuccess(success);

        activeValidationTasks.decrementAndGet();

        log.debug("结束验证性能监控，贷款ID: {}, 验证类型: {}, 耗时: {}ms, 成功: {}", 
            context.getLoanId(), context.getValidationType(), executionTime, success);

        // 检查超时
        checkTimeout(context);

        // 检查性能警告
        checkPerformanceWarning(context);

        // 更新性能指标
        updatePerformanceMetrics(context);
    }

    /**
     * 检查验证超时
     * 实现超时检测和警告日志记录
     * 
     * @param context 性能监控上下文
     */
    private void checkTimeout(PerformanceContext context) {
        if (context.getExecutionTime() > validationTimeoutThreshold) {
            timeoutValidations.incrementAndGet();
            
            log.warn("验证超时检测 - 贷款ID: {}, 验证类型: {}, 执行时间: {}ms, 超时阈值: {}ms", 
                context.getLoanId(), context.getValidationType(), 
                context.getExecutionTime(), validationTimeoutThreshold);
            
            // 记录超时详细信息
            recordTimeoutDetails(context);
        }
    }

    /**
     * 检查性能警告
     * 
     * @param context 性能监控上下文
     */
    private void checkPerformanceWarning(PerformanceContext context) {
        if (context.getExecutionTime() > performanceWarningThreshold) {
            performanceWarnings.incrementAndGet();
            
            log.warn("验证性能警告 - 贷款ID: {}, 验证类型: {}, 执行时间: {}ms, 警告阈值: {}ms", 
                context.getLoanId(), context.getValidationType(), 
                context.getExecutionTime(), performanceWarningThreshold);
            
            // 记录性能警告详细信息
            recordPerformanceWarningDetails(context);
        }
    }

    /**
     * 检查系统负载
     * 实现高负载下的性能降级策略检测
     * 
     * @param context 性能监控上下文
     */
    private void checkSystemLoad(PerformanceContext context) {
        int currentLoad = getCurrentSystemLoad();
        context.setSystemLoad(currentLoad);
        
        if (currentLoad > highLoadThreshold) {
            log.warn("系统高负载检测 - 当前负载: {}%, 高负载阈值: {}%, 贷款ID: {}", 
                currentLoad, highLoadThreshold, context.getLoanId());
            
            context.setHighLoadDetected(true);
            
            // 触发性能降级策略
            triggerPerformanceDegradation(context);
        }
    }

    /**
     * 触发性能降级策略
     * 
     * @param context 性能监控上下文
     */
    private void triggerPerformanceDegradation(PerformanceContext context) {
        log.info("触发性能降级策略 - 贷款ID: {}, 系统负载: {}%", 
            context.getLoanId(), context.getSystemLoad());
        
        // 设置降级标志
        context.setDegradationTriggered(true);
        
        // 可以在这里实现具体的降级策略，比如：
        // 1. 减少验证规则的执行
        // 2. 使用缓存结果
        // 3. 延迟非关键验证
        // 4. 简化验证逻辑
    }

    /**
     * 更新性能指标
     * 
     * @param context 性能监控上下文
     */
    private void updatePerformanceMetrics(PerformanceContext context) {
        String validationType = context.getValidationType();
        
        PerformanceMetrics metrics = metricsMap.computeIfAbsent(validationType, 
            k -> new PerformanceMetrics(validationType));
        
        metrics.addExecution(context.getExecutionTime(), context.isSuccess());
        
        log.debug("更新性能指标 - 验证类型: {}, 平均耗时: {}ms, 成功率: {:.2f}%", 
            validationType, metrics.getAverageExecutionTime(), metrics.getSuccessRate() * 100);
    }

    /**
     * 记录超时详细信息
     * 
     * @param context 性能监控上下文
     */
    private void recordTimeoutDetails(PerformanceContext context) {
        log.error("验证超时详细信息 - " +
            "贷款ID: {}, " +
            "验证类型: {}, " +
            "开始时间: {}, " +
            "结束时间: {}, " +
            "执行时间: {}ms, " +
            "超时阈值: {}ms, " +
            "系统负载: {}%, " +
            "活跃任务数: {}", 
            context.getLoanId(),
            context.getValidationType(),
            DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(context.getStartTime())),
            DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(context.getEndTime())),
            context.getExecutionTime(),
            validationTimeoutThreshold,
            context.getSystemLoad(),
            activeValidationTasks.get());
    }

    /**
     * 记录性能警告详细信息
     * 
     * @param context 性能监控上下文
     */
    private void recordPerformanceWarningDetails(PerformanceContext context) {
        log.warn("验证性能警告详细信息 - " +
            "贷款ID: {}, " +
            "验证类型: {}, " +
            "执行时间: {}ms, " +
            "警告阈值: {}ms, " +
            "系统负载: {}%, " +
            "活跃任务数: {}, " +
            "是否触发降级: {}", 
            context.getLoanId(),
            context.getValidationType(),
            context.getExecutionTime(),
            performanceWarningThreshold,
            context.getSystemLoad(),
            activeValidationTasks.get(),
            context.isDegradationTriggered());
    }

    /**
     * 获取当前系统负载
     * 
     * @return 系统负载百分比
     */
    private int getCurrentSystemLoad() {
        // 简单的负载计算：基于活跃任务数和可用处理器数
        int availableProcessors = Runtime.getRuntime().availableProcessors();
        int currentActiveTasks = activeValidationTasks.get();
        
        // 计算负载百分比
        int loadPercentage = (int) ((double) currentActiveTasks / (availableProcessors * 2) * 100);
        
        // 限制在0-100范围内
        return Math.min(100, Math.max(0, loadPercentage));
    }

    /**
     * 获取性能统计信息
     * 
     * @return 性能统计信息
     */
    public Map<String, Object> getPerformanceStatistics() {
        Map<String, Object> statistics = new ConcurrentHashMap<>();
        
        statistics.put("totalValidations", totalValidations.get());
        statistics.put("timeoutValidations", timeoutValidations.get());
        statistics.put("performanceWarnings", performanceWarnings.get());
        statistics.put("activeValidationTasks", activeValidationTasks.get());
        statistics.put("currentSystemLoad", getCurrentSystemLoad());
        statistics.put("validationTimeoutThreshold", validationTimeoutThreshold);
        statistics.put("performanceWarningThreshold", performanceWarningThreshold);
        statistics.put("highLoadThreshold", highLoadThreshold);
        
        // 添加各验证类型的性能指标
        Map<String, Object> metricsData = new ConcurrentHashMap<>();
        for (Map.Entry<String, PerformanceMetrics> entry : metricsMap.entrySet()) {
            PerformanceMetrics metrics = entry.getValue();
            Map<String, Object> metricData = new ConcurrentHashMap<>();
            metricData.put("totalExecutions", metrics.getTotalExecutions());
            metricData.put("successfulExecutions", metrics.getSuccessfulExecutions());
            metricData.put("averageExecutionTime", metrics.getAverageExecutionTime());
            metricData.put("maxExecutionTime", metrics.getMaxExecutionTime());
            metricData.put("minExecutionTime", metrics.getMinExecutionTime());
            metricData.put("successRate", metrics.getSuccessRate());
            
            metricsData.put(entry.getKey(), metricData);
        }
        statistics.put("validationTypeMetrics", metricsData);
        
        return statistics;
    }

    /**
     * 重置性能统计
     */
    public void resetPerformanceStatistics() {
        log.info("重置验证性能统计数据");
        
        totalValidations.set(0);
        timeoutValidations.set(0);
        performanceWarnings.set(0);
        metricsMap.clear();
    }

    /**
     * 检查是否应该启用异步验证模式
     * 添加异步验证模式支持
     * 
     * @return 是否应该启用异步验证模式
     */
    public boolean shouldEnableAsyncValidation() {
        int currentLoad = getCurrentSystemLoad();
        int activeTasks = activeValidationTasks.get();
        
        // 当系统负载超过阈值或活跃任务数过多时，建议启用异步验证
        boolean shouldEnable = currentLoad > highLoadThreshold || activeTasks > 10;
        
        if (shouldEnable) {
            log.info("建议启用异步验证模式 - 系统负载: {}%, 活跃任务数: {}", currentLoad, activeTasks);
        }
        
        return shouldEnable;
    }

    /**
     * 检查是否应该触发性能降级
     * 
     * @return 是否应该触发性能降级
     */
    public boolean shouldTriggerDegradation() {
        int currentLoad = getCurrentSystemLoad();
        return currentLoad > highLoadThreshold;
    }

    /**
     * 性能监控上下文
     */
    public static class PerformanceContext {
        private final Long loanId;
        private final String validationType;
        private long startTime;
        private long endTime;
        private long executionTime;
        private boolean success;
        private int systemLoad;
        private boolean highLoadDetected;
        private boolean degradationTriggered;

        public PerformanceContext(Long loanId, String validationType) {
            this.loanId = loanId;
            this.validationType = validationType;
        }

        // Getters and Setters
        public Long getLoanId() { return loanId; }
        public String getValidationType() { return validationType; }
        public long getStartTime() { return startTime; }
        public void setStartTime(long startTime) { this.startTime = startTime; }
        public long getEndTime() { return endTime; }
        public void setEndTime(long endTime) { this.endTime = endTime; }
        public long getExecutionTime() { return executionTime; }
        public void setExecutionTime(long executionTime) { this.executionTime = executionTime; }
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public int getSystemLoad() { return systemLoad; }
        public void setSystemLoad(int systemLoad) { this.systemLoad = systemLoad; }
        public boolean isHighLoadDetected() { return highLoadDetected; }
        public void setHighLoadDetected(boolean highLoadDetected) { this.highLoadDetected = highLoadDetected; }
        public boolean isDegradationTriggered() { return degradationTriggered; }
        public void setDegradationTriggered(boolean degradationTriggered) { this.degradationTriggered = degradationTriggered; }
    }

    /**
     * 性能指标
     */
    private static class PerformanceMetrics {
        private final String validationType;
        private final AtomicLong totalExecutions = new AtomicLong(0);
        private final AtomicLong successfulExecutions = new AtomicLong(0);
        private final AtomicLong totalExecutionTime = new AtomicLong(0);
        private volatile long maxExecutionTime = 0;
        private volatile long minExecutionTime = Long.MAX_VALUE;

        public PerformanceMetrics(String validationType) {
            this.validationType = validationType;
        }

        public void addExecution(long executionTime, boolean success) {
            totalExecutions.incrementAndGet();
            if (success) {
                successfulExecutions.incrementAndGet();
            }
            
            totalExecutionTime.addAndGet(executionTime);
            
            // 更新最大和最小执行时间
            if (executionTime > maxExecutionTime) {
                maxExecutionTime = executionTime;
            }
            if (executionTime < minExecutionTime) {
                minExecutionTime = executionTime;
            }
        }

        public long getTotalExecutions() { return totalExecutions.get(); }
        public long getSuccessfulExecutions() { return successfulExecutions.get(); }
        public long getAverageExecutionTime() { 
            long total = totalExecutions.get();
            return total > 0 ? totalExecutionTime.get() / total : 0;
        }
        public long getMaxExecutionTime() { return maxExecutionTime; }
        public long getMinExecutionTime() { return minExecutionTime == Long.MAX_VALUE ? 0 : minExecutionTime; }
        public double getSuccessRate() {
            long total = totalExecutions.get();
            return total > 0 ? (double) successfulExecutions.get() / total : 0.0;
        }
    }
}