package com.ruoyi.credit.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.credit.config.LoanValidationNotificationConfig;
import com.ruoyi.credit.domain.LoanConsistencyValidation;
import com.ruoyi.credit.service.AsyncNotificationProcessor;
import com.ruoyi.credit.service.LoanValidationNotificationService;

/**
 * 异步通知处理器实现类
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Service
public class AsyncNotificationProcessorImpl implements AsyncNotificationProcessor 
{
    private static final Logger log = LoggerFactory.getLogger(AsyncNotificationProcessorImpl.class);

    @Autowired
    private LoanValidationNotificationService loanValidationNotificationService;

    @Autowired
    private LoanValidationNotificationConfig notificationConfig;

    /**
     * 异步通知处理线程池
     */
    private ExecutorService asyncNotificationExecutor;

    /**
     * 任务计数器
     */
    private final AtomicInteger taskCounter = new AtomicInteger(0);

    /**
     * 完成任务计数器
     */
    private final AtomicInteger completedTaskCounter = new AtomicInteger(0);

    /**
     * 失败任务计数器
     */
    private final AtomicInteger failedTaskCounter = new AtomicInteger(0);

    /**
     * 活跃任务映射
     */
    private final Map<String, CompletableFuture<?>> activeTasks = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        log.info("初始化异步通知处理器");
        
        // 创建异步通知处理线程池
        int threadPoolSize = Math.max(2, Runtime.getRuntime().availableProcessors() / 2);
        asyncNotificationExecutor = Executors.newFixedThreadPool(threadPoolSize, r -> {
            Thread thread = new Thread(r, "AsyncNotification-" + taskCounter.incrementAndGet());
            thread.setDaemon(true);
            return thread;
        });
        
        log.info("异步通知处理器初始化完成，线程池大小: {}", threadPoolSize);
    }

    @PreDestroy
    public void destroy() {
        log.info("关闭异步通知处理器");
        
        if (asyncNotificationExecutor != null && !asyncNotificationExecutor.isShutdown()) {
            asyncNotificationExecutor.shutdown();
            try {
                if (!asyncNotificationExecutor.awaitTermination(30, java.util.concurrent.TimeUnit.SECONDS)) {
                    asyncNotificationExecutor.shutdownNow();
                }
            } catch (InterruptedException e) {
                asyncNotificationExecutor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
        
        log.info("异步通知处理器关闭完成");
    }

    @Override
    public CompletableFuture<Boolean> processValidationFailureNotificationAsync(LoanConsistencyValidation validation) {
        log.debug("异步处理验证失败通知，贷款ID: {}", validation.getLoanId());
        
        if (!notificationConfig.isEnabled() || !notificationConfig.isAsyncEnabled()) {
            log.debug("异步通知功能未启用，直接同步处理");
            return CompletableFuture.completedFuture(
                loanValidationNotificationService.sendValidationFailureNotification(validation)
            );
        }

        String taskId = "validation-failure-" + validation.getLoanId() + "-" + System.currentTimeMillis();
        
        CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("开始异步处理验证失败通知，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                
                boolean result = loanValidationNotificationService.sendValidationFailureNotification(validation);
                
                if (result) {
                    completedTaskCounter.incrementAndGet();
                    log.debug("异步验证失败通知处理成功，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                } else {
                    failedTaskCounter.incrementAndGet();
                    log.warn("异步验证失败通知处理失败，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                }
                
                return result;
                
            } catch (Exception e) {
                failedTaskCounter.incrementAndGet();
                log.error("异步处理验证失败通知异常，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId(), e);
                return false;
            } finally {
                // 从活跃任务中移除
                activeTasks.remove(taskId);
            }
        }, asyncNotificationExecutor);
        
        // 添加到活跃任务映射
        activeTasks.put(taskId, future);
        
        return future;
    }

    @Override
    public CompletableFuture<Map<String, Object>> processBatchValidationFailureNotificationsAsync(List<LoanConsistencyValidation> validations) {
        log.info("异步批量处理验证失败通知，数量: {}", validations.size());
        
        if (!notificationConfig.isEnabled() || !notificationConfig.isAsyncEnabled()) {
            log.debug("异步通知功能未启用，直接同步处理");
            return CompletableFuture.completedFuture(
                loanValidationNotificationService.batchSendValidationFailureNotifications(validations)
            );
        }

        String taskId = "batch-validation-failure-" + System.currentTimeMillis();
        
        CompletableFuture<Map<String, Object>> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("开始异步批量处理验证失败通知，任务ID: {}, 数量: {}", taskId, validations.size());
                
                Map<String, Object> result = loanValidationNotificationService.batchSendValidationFailureNotifications(validations);
                
                completedTaskCounter.incrementAndGet();
                log.info("异步批量验证失败通知处理完成，任务ID: {}, 结果: {}", taskId, result);
                
                return result;
                
            } catch (Exception e) {
                failedTaskCounter.incrementAndGet();
                log.error("异步批量处理验证失败通知异常，任务ID: {}", taskId, e);
                
                Map<String, Object> errorResult = new HashMap<>();
                errorResult.put("error", "异步批量处理失败: " + e.getMessage());
                return errorResult;
            } finally {
                // 从活跃任务中移除
                activeTasks.remove(taskId);
            }
        }, asyncNotificationExecutor);
        
        // 添加到活跃任务映射
        activeTasks.put(taskId, future);
        
        return future;
    }

    @Override
    public CompletableFuture<Boolean> processRevalidationSuccessNotificationAsync(LoanConsistencyValidation validation) {
        log.debug("异步处理重新验证成功通知，贷款ID: {}", validation.getLoanId());
        
        if (!notificationConfig.isEnabled() || !notificationConfig.isAsyncEnabled()) {
            log.debug("异步通知功能未启用，直接同步处理");
            return CompletableFuture.completedFuture(
                loanValidationNotificationService.sendRevalidationSuccessNotification(validation)
            );
        }

        String taskId = "revalidation-success-" + validation.getLoanId() + "-" + System.currentTimeMillis();
        
        CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("开始异步处理重新验证成功通知，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                
                boolean result = loanValidationNotificationService.sendRevalidationSuccessNotification(validation);
                
                if (result) {
                    completedTaskCounter.incrementAndGet();
                    log.debug("异步重新验证成功通知处理成功，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                } else {
                    failedTaskCounter.incrementAndGet();
                    log.warn("异步重新验证成功通知处理失败，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId());
                }
                
                return result;
                
            } catch (Exception e) {
                failedTaskCounter.incrementAndGet();
                log.error("异步处理重新验证成功通知异常，任务ID: {}, 贷款ID: {}", taskId, validation.getLoanId(), e);
                return false;
            } finally {
                // 从活跃任务中移除
                activeTasks.remove(taskId);
            }
        }, asyncNotificationExecutor);
        
        // 添加到活跃任务映射
        activeTasks.put(taskId, future);
        
        return future;
    }

    @Override
    public CompletableFuture<Boolean> processValidationExceptionAlertAsync(Long loanId, String errorMessage, String alertLevel) {
        log.debug("异步处理验证异常告警，贷款ID: {}, 告警级别: {}", loanId, alertLevel);
        
        if (!notificationConfig.isEnabled() || !notificationConfig.isAsyncEnabled()) {
            log.debug("异步通知功能未启用，直接同步处理");
            return CompletableFuture.completedFuture(
                loanValidationNotificationService.sendValidationExceptionAlert(loanId, errorMessage, alertLevel)
            );
        }

        String taskId = "validation-exception-" + loanId + "-" + System.currentTimeMillis();
        
        CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
            try {
                log.debug("开始异步处理验证异常告警，任务ID: {}, 贷款ID: {}", taskId, loanId);
                
                boolean result = loanValidationNotificationService.sendValidationExceptionAlert(loanId, errorMessage, alertLevel);
                
                if (result) {
                    completedTaskCounter.incrementAndGet();
                    log.debug("异步验证异常告警处理成功，任务ID: {}, 贷款ID: {}", taskId, loanId);
                } else {
                    failedTaskCounter.incrementAndGet();
                    log.warn("异步验证异常告警处理失败，任务ID: {}, 贷款ID: {}", taskId, loanId);
                }
                
                return result;
                
            } catch (Exception e) {
                failedTaskCounter.incrementAndGet();
                log.error("异步处理验证异常告警异常，任务ID: {}, 贷款ID: {}", taskId, loanId, e);
                return false;
            } finally {
                // 从活跃任务中移除
                activeTasks.remove(taskId);
            }
        }, asyncNotificationExecutor);
        
        // 添加到活跃任务映射
        activeTasks.put(taskId, future);
        
        return future;
    }

    @Override
    public Map<String, Object> getAsyncProcessingStatus() {
        Map<String, Object> status = new HashMap<>();
        
        status.put("enabled", notificationConfig.isEnabled() && notificationConfig.isAsyncEnabled());
        status.put("threadPoolActive", asyncNotificationExecutor != null && !asyncNotificationExecutor.isShutdown());
        status.put("activeTaskCount", activeTasks.size());
        status.put("totalTaskCount", taskCounter.get());
        status.put("completedTaskCount", completedTaskCounter.get());
        status.put("failedTaskCount", failedTaskCounter.get());
        status.put("successRate", calculateSuccessRate());
        status.put("currentTime", DateUtils.getTime());
        
        return status;
    }

    @Override
    public int cleanupCompletedTasks() {
        log.debug("开始清理已完成的异步任务");
        
        int cleanedCount = 0;
        
        try {
            // 清理已完成的任务
            activeTasks.entrySet().removeIf(entry -> {
                CompletableFuture<?> future = entry.getValue();
                if (future.isDone()) {
                    return true;
                }
                return false;
            });
            
            log.debug("清理已完成的异步任务完成，清理数量: {}, 剩余活跃任务: {}", cleanedCount, activeTasks.size());
            
        } catch (Exception e) {
            log.error("清理已完成的异步任务异常", e);
        }
        
        return cleanedCount;
    }

    /**
     * 定时清理已完成的任务
     */
    @Scheduled(fixedDelay = 300000) // 每5分钟执行一次
    public void scheduledCleanupCompletedTasks() {
        if (notificationConfig.isEnabled() && notificationConfig.isAsyncEnabled()) {
            cleanupCompletedTasks();
        }
    }

    /**
     * 计算成功率
     */
    private String calculateSuccessRate() {
        int total = completedTaskCounter.get() + failedTaskCounter.get();
        if (total == 0) {
            return "0%";
        }
        
        double rate = (double) completedTaskCounter.get() / total * 100;
        return String.format("%.2f%%", rate);
    }
}