package com.ruoyi.credit.strategy;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

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

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.credit.monitor.ValidationPerformanceMonitor;
import com.ruoyi.credit.service.ValidationCacheManager;

/**
 * 性能降级策略
 * 实现高负载下的性能降级策略
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Component
public class PerformanceDegradationStrategy {

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

    @Autowired
    private ValidationPerformanceMonitor performanceMonitor;

    @Autowired
    private ValidationCacheManager validationCacheManager;

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

    /** 极高负载阈值 */
    @Value("${loan.validation.performance.extremeLoadThreshold:95}")
    private int extremeLoadThreshold;

    /** 降级策略启用标志 */
    private volatile boolean degradationEnabled = false;

    /** 当前降级级别 */
    private volatile DegradationLevel currentDegradationLevel = DegradationLevel.NONE;

    /** 降级开始时间 */
    private volatile long degradationStartTime = 0;

    /**
     * 降级级别枚举
     */
    public enum DegradationLevel {
        NONE(0, "无降级"),
        LIGHT(1, "轻度降级"),
        MODERATE(2, "中度降级"),
        HEAVY(3, "重度降级"),
        EXTREME(4, "极度降级");

        private final int level;
        private final String description;

        DegradationLevel(int level, String description) {
            this.level = level;
            this.description = description;
        }

        public int getLevel() { return level; }
        public String getDescription() { return description; }
    }

    /**
     * 检查并应用性能降级策略
     * 
     * @param loanId 贷款ID
     * @return 降级策略配置
     */
    public DegradationConfig checkAndApplyDegradation(Long loanId) {
        // 获取当前系统负载
        Map<String, Object> performanceStats = performanceMonitor.getPerformanceStatistics();
        int currentLoad = (Integer) performanceStats.get("currentSystemLoad");
        int activeTasks = (Integer) performanceStats.get("activeValidationTasks");

        log.debug("检查性能降级策略，贷款ID: {}, 系统负载: {}%, 活跃任务数: {}", 
            loanId, currentLoad, activeTasks);

        // 确定降级级别
        DegradationLevel newLevel = determineDegradationLevel(currentLoad, activeTasks);

        // 如果降级级别发生变化，更新状态
        if (newLevel != currentDegradationLevel) {
            updateDegradationLevel(newLevel);
        }

        // 生成降级配置
        DegradationConfig config = generateDegradationConfig(newLevel, loanId);

        log.debug("性能降级策略检查完成，贷款ID: {}, 降级级别: {}, 配置: {}", 
            loanId, newLevel.getDescription(), config);

        return config;
    }

    /**
     * 确定降级级别
     * 
     * @param currentLoad 当前系统负载
     * @param activeTasks 活跃任务数
     * @return 降级级别
     */
    private DegradationLevel determineDegradationLevel(int currentLoad, int activeTasks) {
        // 极度降级：系统负载超过95%或活跃任务数超过50
        if (currentLoad >= extremeLoadThreshold || activeTasks > 50) {
            return DegradationLevel.EXTREME;
        }
        
        // 重度降级：系统负载超过90%或活跃任务数超过30
        if (currentLoad >= 90 || activeTasks > 30) {
            return DegradationLevel.HEAVY;
        }
        
        // 中度降级：系统负载超过85%或活跃任务数超过20
        if (currentLoad >= 85 || activeTasks > 20) {
            return DegradationLevel.MODERATE;
        }
        
        // 轻度降级：系统负载超过高负载阈值或活跃任务数超过15
        if (currentLoad >= highLoadThreshold || activeTasks > 15) {
            return DegradationLevel.LIGHT;
        }
        
        // 无降级
        return DegradationLevel.NONE;
    }

    /**
     * 更新降级级别
     * 
     * @param newLevel 新的降级级别
     */
    private void updateDegradationLevel(DegradationLevel newLevel) {
        DegradationLevel oldLevel = currentDegradationLevel;
        currentDegradationLevel = newLevel;

        if (newLevel == DegradationLevel.NONE) {
            if (degradationEnabled) {
                degradationEnabled = false;
                long degradationDuration = System.currentTimeMillis() - degradationStartTime;
                log.info("性能降级策略结束，持续时间: {}ms, 从 {} 恢复到 {}", 
                    degradationDuration, oldLevel.getDescription(), newLevel.getDescription());
            }
        } else {
            if (!degradationEnabled) {
                degradationEnabled = true;
                degradationStartTime = System.currentTimeMillis();
                log.warn("性能降级策略启动，从 {} 升级到 {}", 
                    oldLevel.getDescription(), newLevel.getDescription());
            } else {
                log.warn("性能降级级别变更，从 {} 变更到 {}", 
                    oldLevel.getDescription(), newLevel.getDescription());
            }
        }
    }

    /**
     * 生成降级配置
     * 
     * @param level 降级级别
     * @param loanId 贷款ID
     * @return 降级配置
     */
    private DegradationConfig generateDegradationConfig(DegradationLevel level, Long loanId) {
        DegradationConfig config = new DegradationConfig();
        config.setLevel(level);
        config.setLoanId(loanId);

        switch (level) {
            case NONE:
                // 无降级：正常执行所有验证规则
                config.setSkipNonCriticalRules(false);
                config.setUseCachedResults(false);
                config.setReduceValidationDepth(false);
                config.setEnableAsyncMode(false);
                config.setValidationTimeout(30000); // 30秒
                config.setMaxRetries(3);
                break;

            case LIGHT:
                // 轻度降级：启用缓存，减少重试次数
                config.setSkipNonCriticalRules(false);
                config.setUseCachedResults(true);
                config.setReduceValidationDepth(false);
                config.setEnableAsyncMode(true);
                config.setValidationTimeout(25000); // 25秒
                config.setMaxRetries(2);
                log.debug("应用轻度降级策略，贷款ID: {}", loanId);
                break;

            case MODERATE:
                // 中度降级：跳过非关键规则，强制使用缓存
                config.setSkipNonCriticalRules(true);
                config.setUseCachedResults(true);
                config.setReduceValidationDepth(true);
                config.setEnableAsyncMode(true);
                config.setValidationTimeout(20000); // 20秒
                config.setMaxRetries(1);
                log.warn("应用中度降级策略，贷款ID: {}", loanId);
                break;

            case HEAVY:
                // 重度降级：只执行核心验证规则
                config.setSkipNonCriticalRules(true);
                config.setUseCachedResults(true);
                config.setReduceValidationDepth(true);
                config.setEnableAsyncMode(true);
                config.setValidationTimeout(15000); // 15秒
                config.setMaxRetries(1);
                config.setOnlyCoreRules(true);
                log.warn("应用重度降级策略，贷款ID: {}", loanId);
                break;

            case EXTREME:
                // 极度降级：只返回缓存结果，不执行新验证
                config.setSkipNonCriticalRules(true);
                config.setUseCachedResults(true);
                config.setReduceValidationDepth(true);
                config.setEnableAsyncMode(true);
                config.setValidationTimeout(10000); // 10秒
                config.setMaxRetries(0);
                config.setOnlyCoreRules(true);
                config.setCacheOnlyMode(true);
                log.error("应用极度降级策略，贷款ID: {}，仅返回缓存结果", loanId);
                break;
        }

        return config;
    }

    /**
     * 应用缓存优先策略
     * 
     * @param loanId 贷款ID
     * @param config 降级配置
     * @return 是否成功获取缓存结果
     */
    public boolean applyCachePriorityStrategy(Long loanId, DegradationConfig config) {
        if (!config.isUseCachedResults()) {
            return false;
        }

        try {
            // 尝试从缓存获取验证结果
            boolean hasCachedResult = validationCacheManager.getCachedValidationResult(loanId) != null;
            
            if (hasCachedResult) {
                log.debug("应用缓存优先策略成功，贷款ID: {}", loanId);
                return true;
            } else {
                log.debug("缓存中无验证结果，贷款ID: {}", loanId);
                return false;
            }
            
        } catch (Exception e) {
            log.error("应用缓存优先策略失败，贷款ID: {}", loanId, e);
            return false;
        }
    }

    /**
     * 获取降级策略状态
     * 
     * @return 降级策略状态信息
     */
    public Map<String, Object> getDegradationStatus() {
        Map<String, Object> status = new HashMap<>();
        
        status.put("degradationEnabled", degradationEnabled);
        status.put("currentDegradationLevel", currentDegradationLevel.name());
        status.put("currentDegradationDescription", currentDegradationLevel.getDescription());
        status.put("highLoadThreshold", highLoadThreshold);
        status.put("extremeLoadThreshold", extremeLoadThreshold);
        
        if (degradationEnabled && degradationStartTime > 0) {
            status.put("degradationStartTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(degradationStartTime)));
            status.put("degradationDuration", System.currentTimeMillis() - degradationStartTime);
        }
        
        // 添加性能监控信息
        Map<String, Object> performanceStats = performanceMonitor.getPerformanceStatistics();
        status.put("currentSystemLoad", performanceStats.get("currentSystemLoad"));
        status.put("activeValidationTasks", performanceStats.get("activeValidationTasks"));
        
        status.put("currentTime", DateUtils.getTime());
        
        return status;
    }

    /**
     * 手动启用降级策略
     * 
     * @param level 降级级别
     * @return 是否启用成功
     */
    public boolean enableDegradationManually(DegradationLevel level) {
        log.info("手动启用性能降级策略，级别: {}", level.getDescription());
        
        try {
            updateDegradationLevel(level);
            return true;
        } catch (Exception e) {
            log.error("手动启用性能降级策略失败", e);
            return false;
        }
    }

    /**
     * 手动禁用降级策略
     * 
     * @return 是否禁用成功
     */
    public boolean disableDegradationManually() {
        log.info("手动禁用性能降级策略");
        
        try {
            updateDegradationLevel(DegradationLevel.NONE);
            return true;
        } catch (Exception e) {
            log.error("手动禁用性能降级策略失败", e);
            return false;
        }
    }

    /**
     * 降级配置类
     */
    public static class DegradationConfig {
        private DegradationLevel level;
        private Long loanId;
        private boolean skipNonCriticalRules;
        private boolean useCachedResults;
        private boolean reduceValidationDepth;
        private boolean enableAsyncMode;
        private long validationTimeout;
        private int maxRetries;
        private boolean onlyCoreRules;
        private boolean cacheOnlyMode;

        // Getters and Setters
        public DegradationLevel getLevel() { return level; }
        public void setLevel(DegradationLevel level) { this.level = level; }
        public Long getLoanId() { return loanId; }
        public void setLoanId(Long loanId) { this.loanId = loanId; }
        public boolean isSkipNonCriticalRules() { return skipNonCriticalRules; }
        public void setSkipNonCriticalRules(boolean skipNonCriticalRules) { this.skipNonCriticalRules = skipNonCriticalRules; }
        public boolean isUseCachedResults() { return useCachedResults; }
        public void setUseCachedResults(boolean useCachedResults) { this.useCachedResults = useCachedResults; }
        public boolean isReduceValidationDepth() { return reduceValidationDepth; }
        public void setReduceValidationDepth(boolean reduceValidationDepth) { this.reduceValidationDepth = reduceValidationDepth; }
        public boolean isEnableAsyncMode() { return enableAsyncMode; }
        public void setEnableAsyncMode(boolean enableAsyncMode) { this.enableAsyncMode = enableAsyncMode; }
        public long getValidationTimeout() { return validationTimeout; }
        public void setValidationTimeout(long validationTimeout) { this.validationTimeout = validationTimeout; }
        public int getMaxRetries() { return maxRetries; }
        public void setMaxRetries(int maxRetries) { this.maxRetries = maxRetries; }
        public boolean isOnlyCoreRules() { return onlyCoreRules; }
        public void setOnlyCoreRules(boolean onlyCoreRules) { this.onlyCoreRules = onlyCoreRules; }
        public boolean isCacheOnlyMode() { return cacheOnlyMode; }
        public void setCacheOnlyMode(boolean cacheOnlyMode) { this.cacheOnlyMode = cacheOnlyMode; }

        @Override
        public String toString() {
            return String.format("DegradationConfig{level=%s, skipNonCritical=%s, useCache=%s, asyncMode=%s, timeout=%d, retries=%d}", 
                level, skipNonCriticalRules, useCachedResults, enableAsyncMode, validationTimeout, maxRetries);
        }
    }
}