package com.ruoyi.credit.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.credit.domain.LoanConsistencyValidation;
import com.ruoyi.credit.service.LoanValidationNotificationService;
import com.ruoyi.notification.domain.NotificationTemplate;
import com.ruoyi.notification.service.INotificationService;

/**
 * 贷款验证通知服务实现类
 * 
 * @author ruoyi
 * @date 2025-12-31
 */
@Service
public class LoanValidationNotificationServiceImpl implements LoanValidationNotificationService 
{
    private static final Logger log = LoggerFactory.getLogger(LoanValidationNotificationServiceImpl.class);

    @Autowired
    private INotificationService notificationService;

    /**
     * 异步通知线程池
     */
    private final ExecutorService notificationExecutor = Executors.newFixedThreadPool(5);

    // 通知模板编码常量
    private static final String TEMPLATE_VALIDATION_FAILURE = "LOAN_VALIDATION_FAILURE";
    private static final String TEMPLATE_REVALIDATION_SUCCESS = "LOAN_REVALIDATION_SUCCESS";
    private static final String TEMPLATE_VALIDATION_EXCEPTION = "LOAN_VALIDATION_EXCEPTION";

    // 通知渠道常量
    private static final String CHANNEL_EMAIL = "EMAIL";
    private static final String CHANNEL_SMS = "SMS";
    private static final String CHANNEL_SYSTEM = "SYSTEM";

    // 接收者类型常量
    private static final String RECIPIENT_TYPE_SECURITY_COMPANY = "SECURITY_COMPANY";
    private static final String RECIPIENT_TYPE_ADMIN = "ADMIN";

    @Override
    public boolean sendValidationFailureNotification(LoanConsistencyValidation validation) {
        log.info("发送验证失败通知，贷款ID: {}", validation.getLoanId());
        
        if (validation == null || validation.getLoanId() == null) {
            log.error("验证记录或贷款ID不能为空");
            return false;
        }

        try {
            // 构建通知参数
            Map<String, Object> parameters = buildValidationFailureParameters(validation);
            
            // 获取接收者信息（这里需要根据实际业务逻辑获取安保公司联系方式）
            String recipientId = validation.getLoanId().toString();
            String recipientEmail = getSecurityCompanyEmail(validation.getLoanId());
            String recipientPhone = getSecurityCompanyPhone(validation.getLoanId());
            
            boolean emailSent = false;
            boolean smsSent = false;
            
            // 发送邮件通知
            if (StringUtils.hasText(recipientEmail)) {
                emailSent = notificationService.sendTemplateNotification(
                    TEMPLATE_VALIDATION_FAILURE,
                    RECIPIENT_TYPE_SECURITY_COMPANY,
                    recipientId,
                    recipientEmail,
                    CHANNEL_EMAIL,
                    parameters,
                    "LOAN_CONSISTENCY",
                    validation.getLoanId().toString()
                );
                
                log.debug("邮件通知发送结果: {}, 贷款ID: {}", emailSent, validation.getLoanId());
            }
            
            // 发送短信通知（高优先级失败）
            if (StringUtils.hasText(recipientPhone) && isHighPriorityFailure(validation)) {
                smsSent = notificationService.sendTemplateNotification(
                    TEMPLATE_VALIDATION_FAILURE,
                    RECIPIENT_TYPE_SECURITY_COMPANY,
                    recipientId,
                    recipientPhone,
                    CHANNEL_SMS,
                    parameters,
                    "LOAN_CONSISTENCY",
                    validation.getLoanId().toString()
                );
                
                log.debug("短信通知发送结果: {}, 贷款ID: {}", smsSent, validation.getLoanId());
            }
            
            // 发送系统内通知
            boolean systemSent = notificationService.sendTemplateNotification(
                TEMPLATE_VALIDATION_FAILURE,
                RECIPIENT_TYPE_SECURITY_COMPANY,
                recipientId,
                recipientId, // 系统通知使用贷款ID作为接收地址
                CHANNEL_SYSTEM,
                parameters,
                "LOAN_CONSISTENCY",
                validation.getLoanId().toString()
            );
            
            log.debug("系统通知发送结果: {}, 贷款ID: {}", systemSent, validation.getLoanId());
            
            boolean overallResult = emailSent || smsSent || systemSent;
            
            if (overallResult) {
                log.info("验证失败通知发送成功，贷款ID: {}, 邮件: {}, 短信: {}, 系统: {}", 
                    validation.getLoanId(), emailSent, smsSent, systemSent);
            } else {
                log.warn("验证失败通知发送失败，贷款ID: {}", validation.getLoanId());
            }
            
            return overallResult;
            
        } catch (Exception e) {
            log.error("发送验证失败通知异常，贷款ID: {}", validation.getLoanId(), e);
            return false;
        }
    }

    @Override
    public CompletableFuture<Boolean> sendValidationFailureNotificationAsync(LoanConsistencyValidation validation) {
        log.debug("异步发送验证失败通知，贷款ID: {}", validation.getLoanId());
        
        return CompletableFuture.supplyAsync(() -> {
            try {
                return sendValidationFailureNotification(validation);
            } catch (Exception e) {
                log.error("异步发送验证失败通知异常，贷款ID: {}", validation.getLoanId(), e);
                return false;
            }
        }, notificationExecutor);
    }

    @Override
    public Map<String, Object> batchSendValidationFailureNotifications(List<LoanConsistencyValidation> validations) {
        log.info("批量发送验证失败通知，数量: {}", validations.size());
        
        Map<String, Object> result = new HashMap<>();
        
        if (CollectionUtils.isEmpty(validations)) {
            result.put("totalCount", 0);
            result.put("successCount", 0);
            result.put("failureCount", 0);
            result.put("message", "没有需要发送通知的验证记录");
            return result;
        }

        try {
            List<CompletableFuture<Boolean>> futures = new ArrayList<>();
            
            // 异步批量发送
            for (LoanConsistencyValidation validation : validations) {
                CompletableFuture<Boolean> future = sendValidationFailureNotificationAsync(validation);
                futures.add(future);
            }
            
            // 等待所有通知发送完成
            List<Boolean> results = new ArrayList<>();
            for (CompletableFuture<Boolean> future : futures) {
                try {
                    Boolean sendResult = future.get();
                    results.add(sendResult);
                } catch (Exception e) {
                    log.error("获取异步通知发送结果异常", e);
                    results.add(false);
                }
            }
            
            // 统计结果
            long successCount = results.stream().filter(Boolean::booleanValue).count();
            long failureCount = results.size() - successCount;
            
            result.put("totalCount", results.size());
            result.put("successCount", successCount);
            result.put("failureCount", failureCount);
            result.put("message", "批量发送验证失败通知完成");
            
            log.info("批量发送验证失败通知完成，总数: {}, 成功: {}, 失败: {}", 
                results.size(), successCount, failureCount);
            
            return result;
            
        } catch (Exception e) {
            log.error("批量发送验证失败通知异常", e);
            result.put("error", "批量发送失败: " + e.getMessage());
            return result;
        }
    }

    @Override
    public boolean sendRevalidationSuccessNotification(LoanConsistencyValidation validation) {
        log.info("发送重新验证成功通知，贷款ID: {}", validation.getLoanId());
        
        if (validation == null || validation.getLoanId() == null) {
            log.error("验证记录或贷款ID不能为空");
            return false;
        }

        try {
            // 构建通知参数
            Map<String, Object> parameters = buildRevalidationSuccessParameters(validation);
            
            // 获取接收者信息
            String recipientId = validation.getLoanId().toString();
            String recipientEmail = getSecurityCompanyEmail(validation.getLoanId());
            
            boolean emailSent = false;
            boolean systemSent = false;
            
            // 发送邮件通知
            if (StringUtils.hasText(recipientEmail)) {
                emailSent = notificationService.sendTemplateNotification(
                    TEMPLATE_REVALIDATION_SUCCESS,
                    RECIPIENT_TYPE_SECURITY_COMPANY,
                    recipientId,
                    recipientEmail,
                    CHANNEL_EMAIL,
                    parameters,
                    "LOAN_CONSISTENCY",
                    validation.getLoanId().toString()
                );
            }
            
            // 发送系统内通知
            systemSent = notificationService.sendTemplateNotification(
                TEMPLATE_REVALIDATION_SUCCESS,
                RECIPIENT_TYPE_SECURITY_COMPANY,
                recipientId,
                recipientId,
                CHANNEL_SYSTEM,
                parameters,
                "LOAN_CONSISTENCY",
                validation.getLoanId().toString()
            );
            
            boolean overallResult = emailSent || systemSent;
            
            if (overallResult) {
                log.info("重新验证成功通知发送成功，贷款ID: {}", validation.getLoanId());
            } else {
                log.warn("重新验证成功通知发送失败，贷款ID: {}", validation.getLoanId());
            }
            
            return overallResult;
            
        } catch (Exception e) {
            log.error("发送重新验证成功通知异常，贷款ID: {}", validation.getLoanId(), e);
            return false;
        }
    }

    @Override
    public boolean sendValidationExceptionAlert(Long loanId, String errorMessage, String alertLevel) {
        log.info("发送验证异常告警，贷款ID: {}, 告警级别: {}", loanId, alertLevel);
        
        if (loanId == null) {
            log.error("贷款ID不能为空");
            return false;
        }

        try {
            // 构建告警参数
            Map<String, Object> parameters = new HashMap<>();
            parameters.put("loanId", loanId);
            parameters.put("errorMessage", errorMessage);
            parameters.put("alertLevel", alertLevel);
            parameters.put("alertTime", DateUtils.getTime());
            parameters.put("systemName", "贷款一致性验证系统");
            
            // 发送给系统管理员
            boolean alertSent = notificationService.sendTemplateNotification(
                TEMPLATE_VALIDATION_EXCEPTION,
                RECIPIENT_TYPE_ADMIN,
                "admin",
                "admin@example.com", // 这里应该从配置中获取管理员邮箱
                CHANNEL_EMAIL,
                parameters,
                "LOAN_CONSISTENCY",
                loanId.toString()
            );
            
            if (alertSent) {
                log.info("验证异常告警发送成功，贷款ID: {}", loanId);
            } else {
                log.warn("验证异常告警发送失败，贷款ID: {}", loanId);
            }
            
            return alertSent;
            
        } catch (Exception e) {
            log.error("发送验证异常告警异常，贷款ID: {}", loanId, e);
            return false;
        }
    }

    @Override
    public boolean initializeNotificationTemplates() {
        log.info("初始化贷款验证通知模板");
        
        try {
            boolean result = true;
            
            // 创建验证失败通知模板
            result &= createValidationFailureTemplate();
            
            // 创建重新验证成功通知模板
            result &= createRevalidationSuccessTemplate();
            
            // 创建验证异常告警模板
            result &= createValidationExceptionTemplate();
            
            if (result) {
                log.info("贷款验证通知模板初始化成功");
            } else {
                log.warn("贷款验证通知模板初始化部分失败");
            }
            
            return result;
            
        } catch (Exception e) {
            log.error("初始化贷款验证通知模板异常", e);
            return false;
        }
    }

    @Override
    public Map<String, Object> getNotificationStatistics(String startDate, String endDate) {
        log.debug("获取通知发送统计，开始日期: {}, 结束日期: {}", startDate, endDate);
        
        try {
            // 调用通知服务的统计接口
            Map<String, Object> statistics = notificationService.getNotificationStatistics(startDate, endDate);
            
            // 添加贷款验证相关的统计信息
            statistics.put("businessType", "LOAN_CONSISTENCY");
            statistics.put("supportedTemplates", java.util.Arrays.asList(
                TEMPLATE_VALIDATION_FAILURE,
                TEMPLATE_REVALIDATION_SUCCESS,
                TEMPLATE_VALIDATION_EXCEPTION
            ));
            
            return statistics;
            
        } catch (Exception e) {
            log.error("获取通知发送统计异常", e);
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("error", "获取统计信息失败: " + e.getMessage());
            return errorResult;
        }
    }

    /**
     * 构建验证失败通知参数
     */
    private Map<String, Object> buildValidationFailureParameters(LoanConsistencyValidation validation) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("loanId", validation.getLoanId());
        parameters.put("failureReason", validation.getFailureReason());
        parameters.put("validationTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, validation.getValidationTime()));
        parameters.put("validationScore", validation.getValidationScore());
        parameters.put("validationResult", validation.getValidationResult());
        parameters.put("ruleVersion", validation.getRuleVersion());
        parameters.put("validatedBy", validation.getValidatedBy());
        
        // 添加修正建议
        parameters.put("correctionSuggestions", generateCorrectionSuggestions(validation));
        
        return parameters;
    }

    /**
     * 构建重新验证成功通知参数
     */
    private Map<String, Object> buildRevalidationSuccessParameters(LoanConsistencyValidation validation) {
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("loanId", validation.getLoanId());
        parameters.put("validationTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, validation.getValidationTime()));
        parameters.put("validationScore", validation.getValidationScore());
        parameters.put("validationResult", validation.getValidationResult());
        parameters.put("validatedBy", validation.getValidatedBy());
        
        return parameters;
    }

    /**
     * 生成修正建议
     */
    private String generateCorrectionSuggestions(LoanConsistencyValidation validation) {
        StringBuilder suggestions = new StringBuilder();
        
        String failureReason = validation.getFailureReason();
        if (StringUtils.hasText(failureReason)) {
            if (failureReason.contains("债权凭证不存在")) {
                suggestions.append("1. 请检查债权凭证是否已正确生成并上传到区块链系统；");
            }
            if (failureReason.contains("合同信息不匹配")) {
                suggestions.append("2. 请核对服务周期中的贷款合同信息是否与债权凭证一致；");
            }
            if (failureReason.contains("金额不一致")) {
                suggestions.append("3. 请检查贷款金额、服务费用等数值是否正确录入；");
            }
            if (failureReason.contains("日期不一致")) {
                suggestions.append("4. 请核对合同日期、服务周期等时间信息是否匹配；");
            }
        }
        
        if (suggestions.length() == 0) {
            suggestions.append("请联系系统管理员或查看详细验证日志以获取具体的修正指导。");
        }
        
        return suggestions.toString();
    }

    /**
     * 获取安保公司邮箱（模拟实现，实际应从数据库获取）
     */
    private String getSecurityCompanyEmail(Long loanId) {
        // 这里应该根据贷款ID查询对应的安保公司联系方式
        // 目前返回模拟邮箱
        return "security@example.com";
    }

    /**
     * 获取安保公司电话（模拟实现，实际应从数据库获取）
     */
    private String getSecurityCompanyPhone(Long loanId) {
        // 这里应该根据贷款ID查询对应的安保公司联系方式
        // 目前返回模拟电话
        return "13800138000";
    }

    /**
     * 判断是否为高优先级失败（需要短信通知）
     */
    private boolean isHighPriorityFailure(LoanConsistencyValidation validation) {
        if (validation.getValidationScore() != null && validation.getValidationScore() == 0) {
            return true; // 完全失败
        }
        
        String failureReason = validation.getFailureReason();
        if (StringUtils.hasText(failureReason)) {
            // 债权凭证不存在是高优先级问题
            if (failureReason.contains("债权凭证不存在") || failureReason.contains("系统异常")) {
                return true;
            }
        }
        
        return false;
    }

    /**
     * 创建验证失败通知模板
     */
    private boolean createValidationFailureTemplate() {
        try {
            NotificationTemplate template = new NotificationTemplate();
            template.setTemplateCode(TEMPLATE_VALIDATION_FAILURE);
            template.setTemplateName("贷款一致性验证失败通知");
            template.setNotificationType("VALIDATION_FAILURE");
            template.setSupportedChannels("EMAIL,SMS,SYSTEM");
            template.setSubjectTemplate("贷款一致性验证失败 - 贷款ID: ${loanId}");
            template.setContentTemplate(
                "尊敬的用户，\n\n" +
                "您的贷款申请（贷款ID: ${loanId}）在一致性验证过程中未能通过验证。\n\n" +
                "验证时间: ${validationTime}\n" +
                "验证得分: ${validationScore}/100\n" +
                "失败原因: ${failureReason}\n" +
                "验证结果: ${validationResult}\n\n" +
                "修正建议:\n${correctionSuggestions}\n\n" +
                "请根据以上信息及时修正相关数据，修正完成后系统将自动重新进行验证。\n" +
                "如有疑问，请联系系统管理员。\n\n" +
                "此致\n" +
                "数字债权服务系统"
            );
            template.setTemplateStatus("ACTIVE");
            template.setBusinessType("LOAN_CONSISTENCY");
            template.setDescription("贷款一致性验证失败时发送给安保公司的通知模板");
            
            return notificationService.createNotificationTemplate(template);
            
        } catch (Exception e) {
            log.error("创建验证失败通知模板异常", e);
            return false;
        }
    }

    /**
     * 创建重新验证成功通知模板
     */
    private boolean createRevalidationSuccessTemplate() {
        try {
            NotificationTemplate template = new NotificationTemplate();
            template.setTemplateCode(TEMPLATE_REVALIDATION_SUCCESS);
            template.setTemplateName("贷款重新验证成功通知");
            template.setNotificationType("REVALIDATION_SUCCESS");
            template.setSupportedChannels("EMAIL,SYSTEM");
            template.setSubjectTemplate("贷款重新验证成功 - 贷款ID: ${loanId}");
            template.setContentTemplate(
                "尊敬的用户，\n\n" +
                "您的贷款申请（贷款ID: ${loanId}）已成功通过重新验证。\n\n" +
                "验证时间: ${validationTime}\n" +
                "验证得分: ${validationScore}/100\n" +
                "验证结果: ${validationResult}\n" +
                "验证人员: ${validatedBy}\n\n" +
                "您的贷款记录现已重新包含在银行的贷款管理界面中。\n" +
                "感谢您的配合！\n\n" +
                "此致\n" +
                "数字债权服务系统"
            );
            template.setTemplateStatus("ACTIVE");
            template.setBusinessType("LOAN_CONSISTENCY");
            template.setDescription("贷款重新验证成功时发送给安保公司的通知模板");
            
            return notificationService.createNotificationTemplate(template);
            
        } catch (Exception e) {
            log.error("创建重新验证成功通知模板异常", e);
            return false;
        }
    }

    /**
     * 创建验证异常告警模板
     */
    private boolean createValidationExceptionTemplate() {
        try {
            NotificationTemplate template = new NotificationTemplate();
            template.setTemplateCode(TEMPLATE_VALIDATION_EXCEPTION);
            template.setTemplateName("贷款验证系统异常告警");
            template.setNotificationType("SYSTEM_ALERT");
            template.setSupportedChannels("EMAIL,SMS");
            template.setSubjectTemplate("【系统告警】${systemName} - 验证异常");
            template.setContentTemplate(
                "系统管理员，\n\n" +
                "贷款一致性验证系统发生异常，请及时处理。\n\n" +
                "告警级别: ${alertLevel}\n" +
                "贷款ID: ${loanId}\n" +
                "异常信息: ${errorMessage}\n" +
                "告警时间: ${alertTime}\n" +
                "系统名称: ${systemName}\n\n" +
                "请登录系统查看详细日志并及时处理异常。\n\n" +
                "此致\n" +
                "系统监控服务"
            );
            template.setTemplateStatus("ACTIVE");
            template.setBusinessType("LOAN_CONSISTENCY");
            template.setDescription("贷款验证系统异常时发送给管理员的告警模板");
            
            return notificationService.createNotificationTemplate(template);
            
        } catch (Exception e) {
            log.error("创建验证异常告警模板异常", e);
            return false;
        }
    }
}