package com.ruoyi.credit.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.credit.domain.LoanConsistencyValidation;
import com.ruoyi.credit.monitor.ValidationPerformanceMonitor;
import com.ruoyi.credit.service.AsyncValidationService;
import com.ruoyi.credit.service.ILoanConsistencyService;

/**
 * 异步验证服务实现类
 * 添加异步验证模式支持
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Service
public class AsyncValidationServiceImpl implements AsyncValidationService {

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

    @Autowired
    private ILoanConsistencyService loanConsistencyService;

    @Autowired
    private ValidationPerformanceMonitor performanceMonitor;

    @Autowired
    @Qualifier("validationTaskExecutor")
    private Executor validationTaskExecutor;

    @Autowired
    @Qualifier("batchProcessTaskExecutor")
    private Executor batchProcessTaskExecutor;

    /** 异步任务状态跟踪 */
    private final Map<String, AsyncValidationTask> asyncTasks = new ConcurrentHashMap<>();

    @Override
    public CompletableFuture<LoanConsistencyValidation> validateLoanAsync(Long loanId, String priority) {
        log.info("开始异步验证贷款，贷款ID: {}, 优先级: {}", loanId, priority);

        if (loanId == null) {
            CompletableFuture<LoanConsistencyValidation> future = new CompletableFuture<>();
            future.completeExceptionally(new IllegalArgumentException("贷款ID不能为空"));
            return future;
        }

        // 创建异步任务
        String taskId = generateTaskId();
        AsyncValidationTask task = new AsyncValidationTask(taskId, "SINGLE_VALIDATION", loanId);
        asyncTasks.put(taskId, task);

        // 检查是否应该启用异步验证模式
        if (!performanceMonitor.shouldEnableAsyncValidation()) {
            log.debug("当前系统负载较低，使用同步验证模式");
            try {
                LoanConsistencyValidation result = loanConsistencyService.validateLoanConsistency(loanId, null, null);
                task.setStatus("COMPLETED");
                task.setEndTime(System.currentTimeMillis());
                return CompletableFuture.completedFuture(result);
            } catch (Exception e) {
                task.setStatus("FAILED");
                task.setEndTime(System.currentTimeMillis());
                task.setErrorMessage(e.getMessage());
                CompletableFuture<LoanConsistencyValidation> future = new CompletableFuture<>();
                future.completeExceptionally(e);
                return future;
            }
        }

        // 使用异步执行器执行验证
        CompletableFuture<LoanConsistencyValidation> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("异步执行贷款验证，任务ID: {}, 贷款ID: {}", taskId, loanId);
                
                task.setStatus("RUNNING");
                
                // 开始性能监控
                ValidationPerformanceMonitor.PerformanceContext perfContext = 
                    performanceMonitor.startValidationMonitoring(loanId, "ASYNC_SINGLE_VALIDATION");

                try {
                    // 执行验证
                    LoanConsistencyValidation result = loanConsistencyService.validateLoanConsistency(loanId, null, null);
                    
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, result.isPassed());
                    
                    task.setStatus("COMPLETED");
                    task.setEndTime(System.currentTimeMillis());
                    
                    log.info("异步贷款验证完成，任务ID: {}, 贷款ID: {}, 验证状态: {}", 
                        taskId, loanId, result.getValidationStatus());
                    
                    return result;
                    
                } catch (Exception e) {
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, false);
                    throw e;
                }
                
            } catch (Exception e) {
                log.error("异步贷款验证失败，任务ID: {}, 贷款ID: {}", taskId, loanId, e);
                
                task.setStatus("FAILED");
                task.setEndTime(System.currentTimeMillis());
                task.setErrorMessage(e.getMessage());
                
                throw new RuntimeException("异步验证失败: " + e.getMessage(), e);
            }
        }, validationTaskExecutor);

        // 设置任务的Future引用
        task.setFuture(future);

        return future;
    }

    @Override
    public CompletableFuture<List<LoanConsistencyValidation>> batchValidateLoansAsync(List<Long> loanIds, int batchSize) {
        log.info("开始异步批量验证贷款，贷款数量: {}, 批次大小: {}", loanIds.size(), batchSize);

        if (CollectionUtils.isEmpty(loanIds)) {
            return CompletableFuture.completedFuture(new ArrayList<>());
        }

        // 创建异步任务
        String taskId = generateTaskId();
        AsyncValidationTask task = new AsyncValidationTask(taskId, "BATCH_VALIDATION", null);
        task.setTotalCount(loanIds.size());
        asyncTasks.put(taskId, task);

        // 使用批量处理执行器执行验证
        CompletableFuture<List<LoanConsistencyValidation>> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("异步执行批量贷款验证，任务ID: {}, 贷款数量: {}", taskId, loanIds.size());
                
                task.setStatus("RUNNING");
                
                // 开始性能监控
                ValidationPerformanceMonitor.PerformanceContext perfContext = 
                    performanceMonitor.startValidationMonitoring(null, "ASYNC_BATCH_VALIDATION");

                try {
                    List<LoanConsistencyValidation> results = new ArrayList<>();
                    
                    // 分批处理
                    for (int i = 0; i < loanIds.size(); i += batchSize) {
                        int endIndex = Math.min(i + batchSize, loanIds.size());
                        List<Long> batchLoanIds = loanIds.subList(i, endIndex);
                        
                        log.debug("处理批次 {}-{}, 数量: {}", i + 1, endIndex, batchLoanIds.size());
                        
                        // 批量验证当前批次
                        List<LoanConsistencyValidation> batchResults = 
                            loanConsistencyService.batchValidateLoans(batchLoanIds);
                        
                        results.addAll(batchResults);
                        
                        // 更新任务进度
                        task.setProcessedCount(results.size());
                        
                        // 检查是否应该触发性能降级
                        if (performanceMonitor.shouldTriggerDegradation()) {
                            log.warn("检测到高负载，触发性能降级策略，任务ID: {}", taskId);
                            // 可以在这里实现降级策略，比如增加批次间的延迟
                            try {
                                Thread.sleep(100); // 短暂延迟
                            } catch (InterruptedException e) {
                                Thread.currentThread().interrupt();
                                break;
                            }
                        }
                    }
                    
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, true);
                    
                    task.setStatus("COMPLETED");
                    task.setEndTime(System.currentTimeMillis());
                    
                    log.info("异步批量贷款验证完成，任务ID: {}, 处理数量: {}, 成功数量: {}", 
                        taskId, results.size(), 
                        results.stream().filter(LoanConsistencyValidation::isPassed).count());
                    
                    return results;
                    
                } catch (Exception e) {
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, false);
                    throw e;
                }
                
            } catch (Exception e) {
                log.error("异步批量贷款验证失败，任务ID: {}", taskId, e);
                
                task.setStatus("FAILED");
                task.setEndTime(System.currentTimeMillis());
                task.setErrorMessage(e.getMessage());
                
                throw new RuntimeException("异步批量验证失败: " + e.getMessage(), e);
            }
        }, batchProcessTaskExecutor);

        // 设置任务的Future引用
        task.setFuture(future);

        return future;
    }

    @Override
    public CompletableFuture<LoanConsistencyValidation> revalidateLoanAsync(Long loanId, String reason) {
        log.info("开始异步重新验证贷款，贷款ID: {}, 原因: {}", loanId, reason);

        if (loanId == null) {
            CompletableFuture<LoanConsistencyValidation> future = new CompletableFuture<>();
            future.completeExceptionally(new IllegalArgumentException("贷款ID不能为空"));
            return future;
        }

        // 创建异步任务
        String taskId = generateTaskId();
        AsyncValidationTask task = new AsyncValidationTask(taskId, "REVALIDATION", loanId);
        asyncTasks.put(taskId, task);

        // 使用异步执行器执行重新验证
        CompletableFuture<LoanConsistencyValidation> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("异步执行贷款重新验证，任务ID: {}, 贷款ID: {}", taskId, loanId);
                
                task.setStatus("RUNNING");
                
                // 开始性能监控
                ValidationPerformanceMonitor.PerformanceContext perfContext = 
                    performanceMonitor.startValidationMonitoring(loanId, "ASYNC_REVALIDATION");

                try {
                    // 执行重新验证
                    LoanConsistencyValidation result = loanConsistencyService.revalidateLoan(loanId);
                    
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, result.isPassed());
                    
                    task.setStatus("COMPLETED");
                    task.setEndTime(System.currentTimeMillis());
                    
                    log.info("异步贷款重新验证完成，任务ID: {}, 贷款ID: {}, 验证状态: {}", 
                        taskId, loanId, result.getValidationStatus());
                    
                    return result;
                    
                } catch (Exception e) {
                    // 结束性能监控
                    performanceMonitor.endValidationMonitoring(perfContext, false);
                    throw e;
                }
                
            } catch (Exception e) {
                log.error("异步贷款重新验证失败，任务ID: {}, 贷款ID: {}", taskId, loanId, e);
                
                task.setStatus("FAILED");
                task.setEndTime(System.currentTimeMillis());
                task.setErrorMessage(e.getMessage());
                
                throw new RuntimeException("异步重新验证失败: " + e.getMessage(), e);
            }
        }, validationTaskExecutor);

        // 设置任务的Future引用
        task.setFuture(future);

        return future;
    }

    @Override
    public Map<String, Object> getAsyncValidationTaskStatus(String taskId) {
        log.debug("获取异步验证任务状态，任务ID: {}", taskId);

        AsyncValidationTask task = asyncTasks.get(taskId);
        if (task == null) {
            Map<String, Object> result = new HashMap<>();
            result.put("error", "任务不存在");
            return result;
        }

        Map<String, Object> status = new HashMap<>();
        status.put("taskId", task.getTaskId());
        status.put("taskType", task.getTaskType());
        status.put("loanId", task.getLoanId());
        status.put("status", task.getStatus());
        status.put("startTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(task.getStartTime())));
        
        if (task.getEndTime() > 0) {
            status.put("endTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date(task.getEndTime())));
            status.put("executionTime", task.getEndTime() - task.getStartTime());
        }
        
        if (task.getTotalCount() > 0) {
            status.put("totalCount", task.getTotalCount());
            status.put("processedCount", task.getProcessedCount());
            status.put("progress", (double) task.getProcessedCount() / task.getTotalCount() * 100);
        }
        
        if (task.getErrorMessage() != null) {
            status.put("errorMessage", task.getErrorMessage());
        }

        return status;
    }

    @Override
    public boolean cancelAsyncValidationTask(String taskId) {
        log.info("取消异步验证任务，任务ID: {}", taskId);

        AsyncValidationTask task = asyncTasks.get(taskId);
        if (task == null) {
            log.warn("要取消的任务不存在，任务ID: {}", taskId);
            return false;
        }

        try {
            // 取消Future任务
            if (task.getFuture() != null && !task.getFuture().isDone()) {
                boolean cancelled = task.getFuture().cancel(true);
                if (cancelled) {
                    task.setStatus("CANCELLED");
                    task.setEndTime(System.currentTimeMillis());
                    log.info("异步验证任务取消成功，任务ID: {}", taskId);
                    return true;
                } else {
                    log.warn("异步验证任务取消失败，任务ID: {}", taskId);
                    return false;
                }
            } else {
                log.warn("异步验证任务已完成或不存在Future，无法取消，任务ID: {}", taskId);
                return false;
            }
        } catch (Exception e) {
            log.error("取消异步验证任务异常，任务ID: {}", taskId, e);
            return false;
        }
    }

    @Override
    public Map<String, Object> getAsyncValidationServiceStatus() {
        log.debug("获取异步验证服务状态");

        Map<String, Object> status = new HashMap<>();
        
        // 统计任务状态
        long runningTasks = asyncTasks.values().stream().filter(task -> "RUNNING".equals(task.getStatus())).count();
        long completedTasks = asyncTasks.values().stream().filter(task -> "COMPLETED".equals(task.getStatus())).count();
        long failedTasks = asyncTasks.values().stream().filter(task -> "FAILED".equals(task.getStatus())).count();
        long cancelledTasks = asyncTasks.values().stream().filter(task -> "CANCELLED".equals(task.getStatus())).count();
        
        status.put("totalTasks", asyncTasks.size());
        status.put("runningTasks", runningTasks);
        status.put("completedTasks", completedTasks);
        status.put("failedTasks", failedTasks);
        status.put("cancelledTasks", cancelledTasks);
        
        // 添加性能监控信息
        status.put("shouldEnableAsyncValidation", performanceMonitor.shouldEnableAsyncValidation());
        status.put("shouldTriggerDegradation", performanceMonitor.shouldTriggerDegradation());
        
        // 添加性能统计信息
        Map<String, Object> performanceStats = performanceMonitor.getPerformanceStatistics();
        status.put("performanceStatistics", performanceStats);
        
        status.put("currentTime", DateUtils.getTime());
        
        return status;
    }

    /**
     * 生成任务ID
     * 
     * @return 任务ID
     */
    private String generateTaskId() {
        return "ASYNC_VALIDATION_" + UUID.randomUUID().toString().replace("-", "").substring(0, 8);
    }

    /**
     * 清理已完成的任务
     * 定期清理已完成的任务以避免内存泄漏
     */
    public void cleanupCompletedTasks() {
        log.debug("开始清理已完成的异步验证任务");
        
        long currentTime = System.currentTimeMillis();
        int cleanupCount = 0;
        
        // 清理1小时前完成的任务
        long cleanupThreshold = 60 * 60 * 1000; // 1小时
        
        asyncTasks.entrySet().removeIf(entry -> {
            AsyncValidationTask task = entry.getValue();
            boolean shouldCleanup = task.getEndTime() > 0 && 
                (currentTime - task.getEndTime()) > cleanupThreshold;
            
            if (shouldCleanup) {
                log.debug("清理已完成的任务，任务ID: {}, 状态: {}", task.getTaskId(), task.getStatus());
            }
            
            return shouldCleanup;
        });
        
        if (cleanupCount > 0) {
            log.info("清理已完成的异步验证任务数量: {}", cleanupCount);
        }
    }

    /**
     * 异步验证任务
     */
    private static class AsyncValidationTask {
        private final String taskId;
        private final String taskType;
        private final Long loanId;
        private final long startTime;
        private long endTime;
        private String status;
        private String errorMessage;
        private int totalCount;
        private int processedCount;
        private CompletableFuture<?> future;

        public AsyncValidationTask(String taskId, String taskType, Long loanId) {
            this.taskId = taskId;
            this.taskType = taskType;
            this.loanId = loanId;
            this.startTime = System.currentTimeMillis();
            this.status = "CREATED";
        }

        // Getters and Setters
        public String getTaskId() { return taskId; }
        public String getTaskType() { return taskType; }
        public Long getLoanId() { return loanId; }
        public long getStartTime() { return startTime; }
        public long getEndTime() { return endTime; }
        public void setEndTime(long endTime) { this.endTime = endTime; }
        public String getStatus() { return status; }
        public void setStatus(String status) { this.status = status; }
        public String getErrorMessage() { return errorMessage; }
        public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; }
        public int getTotalCount() { return totalCount; }
        public void setTotalCount(int totalCount) { this.totalCount = totalCount; }
        public int getProcessedCount() { return processedCount; }
        public void setProcessedCount(int processedCount) { this.processedCount = processedCount; }
        public CompletableFuture<?> getFuture() { return future; }
        public void setFuture(CompletableFuture<?> future) { this.future = future; }
    }
}