package com.ruoyi.credit.listener;

import java.util.Date;
import java.util.concurrent.CompletableFuture;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.credit.event.LoanChangeEvent;
import com.ruoyi.credit.service.ILoanConsistencyService;
import com.ruoyi.credit.service.ValidationQueueManager;

/**
 * 贷款记录变更监听器
 * 监听贷款记录的新增、修改事件，自动触发一致性验证
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Component
public class LoanChangeListener {

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

    @Autowired
    private ILoanConsistencyService loanConsistencyService;

    @Autowired
    private ValidationQueueManager validationQueueManager;

    /**
     * 监听贷款记录新增事件
     * 
     * @param event 贷款变更事件
     */
    @EventListener
    @Async("validationTaskExecutor")
    public void handleLoanCreated(LoanChangeEvent event) {
        if (LoanChangeEvent.EventType.CREATED.equals(event.getEventType())) {
            log.info("监听到贷款记录新增事件，贷款ID: {}, 触发时间: {}", 
                event.getLoanId(), DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, event.getEventTime()));
            
            try {
                // 将新增的贷款记录加入验证队列，设置高优先级
                validationQueueManager.addToValidationQueue(event.getLoanId(), 
                    ValidationQueueManager.Priority.HIGH, "贷款记录新增触发");
                
                log.info("贷款记录新增验证任务已加入队列，贷款ID: {}", event.getLoanId());
                
            } catch (Exception e) {
                log.error("处理贷款记录新增事件失败，贷款ID: {}", event.getLoanId(), e);
            }
        }
    }

    /**
     * 监听贷款记录修改事件
     * 
     * @param event 贷款变更事件
     */
    @EventListener
    @Async("validationTaskExecutor")
    public void handleLoanUpdated(LoanChangeEvent event) {
        if (LoanChangeEvent.EventType.UPDATED.equals(event.getEventType())) {
            log.info("监听到贷款记录修改事件，贷款ID: {}, 触发时间: {}", 
                event.getLoanId(), DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, event.getEventTime()));
            
            try {
                // 检查是否需要重新验证
                boolean needsRevalidation = loanConsistencyService.needsRevalidation(event.getLoanId());
                
                if (needsRevalidation) {
                    // 将修改的贷款记录加入验证队列，设置中等优先级
                    validationQueueManager.addToValidationQueue(event.getLoanId(), 
                        ValidationQueueManager.Priority.MEDIUM, "贷款记录修改触发");
                    
                    log.info("贷款记录修改验证任务已加入队列，贷款ID: {}", event.getLoanId());
                } else {
                    log.debug("贷款记录无需重新验证，贷款ID: {}", event.getLoanId());
                }
                
            } catch (Exception e) {
                log.error("处理贷款记录修改事件失败，贷款ID: {}", event.getLoanId(), e);
            }
        }
    }

    /**
     * 监听债权凭证变更事件
     * 
     * @param event 贷款变更事件
     */
    @EventListener
    @Async("validationTaskExecutor")
    public void handleCreditCertificateChanged(LoanChangeEvent event) {
        if (LoanChangeEvent.EventType.CREDIT_CHANGED.equals(event.getEventType())) {
            log.info("监听到债权凭证变更事件，贷款ID: {}, 债权凭证ID: {}, 触发时间: {}", 
                event.getLoanId(), event.getCreditId(), 
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, event.getEventTime()));
            
            try {
                // 债权凭证变更需要立即重新验证，设置最高优先级
                validationQueueManager.addToValidationQueue(event.getLoanId(), 
                    ValidationQueueManager.Priority.URGENT, "债权凭证变更触发");
                
                log.info("债权凭证变更验证任务已加入队列，贷款ID: {}", event.getLoanId());
                
            } catch (Exception e) {
                log.error("处理债权凭证变更事件失败，贷款ID: {}", event.getLoanId(), e);
            }
        }
    }

    /**
     * 监听服务周期变更事件
     * 
     * @param event 贷款变更事件
     */
    @EventListener
    @Async("validationTaskExecutor")
    public void handleServicePeriodChanged(LoanChangeEvent event) {
        if (LoanChangeEvent.EventType.SERVICE_PERIOD_CHANGED.equals(event.getEventType())) {
            log.info("监听到服务周期变更事件，贷款ID: {}, 服务周期ID: {}, 触发时间: {}", 
                event.getLoanId(), event.getServicePeriodId(), 
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, event.getEventTime()));
            
            try {
                // 服务周期变更需要重新验证，设置高优先级
                validationQueueManager.addToValidationQueue(event.getLoanId(), 
                    ValidationQueueManager.Priority.HIGH, "服务周期变更触发");
                
                log.info("服务周期变更验证任务已加入队列，贷款ID: {}", event.getLoanId());
                
            } catch (Exception e) {
                log.error("处理服务周期变更事件失败，贷款ID: {}", event.getLoanId(), e);
            }
        }
    }

    /**
     * 监听批量验证请求事件
     * 
     * @param event 贷款变更事件
     */
    @EventListener
    @Async("validationTaskExecutor")
    public void handleBatchValidationRequest(LoanChangeEvent event) {
        if (LoanChangeEvent.EventType.BATCH_VALIDATION_REQUEST.equals(event.getEventType())) {
            log.info("监听到批量验证请求事件，触发时间: {}", 
                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, event.getEventTime()));
            
            try {
                // 异步执行批量验证
                CompletableFuture.runAsync(() -> {
                    try {
                        loanConsistencyService.validateAllLoansInBackground();
                        log.info("批量验证请求处理完成");
                    } catch (Exception e) {
                        log.error("批量验证请求处理失败", e);
                    }
                });
                
            } catch (Exception e) {
                log.error("处理批量验证请求事件失败", e);
            }
        }
    }
}