package com.example.demo.service;

import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

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.Service;

/**
 * 验证码服务
 */
@Service
public class VerificationCodeService {
    
    private static final Logger logger = LoggerFactory.getLogger(VerificationCodeService.class);
    
    @Autowired
    private TencentSesMailService tencentSesMailService;
    
    @Value("${tencent.ses.template-id:0}")
    private Long templateId;
    
    // 在构造函数中记录配置值，用于调试
    public VerificationCodeService() {
        // 构造函数用于初始化
    }
    
    // 使用@PostConstruct确保在注入后记录配置
    @jakarta.annotation.PostConstruct
    public void init() {
        logger.info("=== 邮件服务配置初始化 ===");
        logger.info("模板ID配置值: {}", templateId);
        logger.info("如果为0或null，将使用开发模式");
    }
    
    // 使用内存存储验证码
    private final ConcurrentHashMap<String, String> verificationCodes = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Long> rateLimits = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    /**
     * 统一归一化邮箱（去首尾空格并小写），避免大小写或空白导致匹配失败
     */
    private String normalizeEmail(String email) {
        if (email == null) return null;
        return email.trim().toLowerCase();
    }
    
    /**
     * 验证码长度
     */
    private static final int CODE_LENGTH = 6;
    
    /**
     * 验证码有效期（分钟）
     */
    private static final int CODE_EXPIRE_MINUTES = 5;
    
    /**
     * 发送频率限制（秒）
     */
    private static final int SEND_INTERVAL_SECONDS = 60;
    
    /**
     * 生成验证码
     */
    public String generateVerificationCode() {
        Random random = new Random();
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < CODE_LENGTH; i++) {
            code.append(random.nextInt(10));
        }
        return code.toString();
    }
    
    
    /**
     * 发送邮件验证码
     */
    public boolean sendEmailVerificationCode(String email) {
        try {
            // 归一化邮箱并检查发送频率限制
            String normEmail = normalizeEmail(email);
            String rateLimitKey = "email_rate_limit:" + normEmail;
            Long lastSendTime = rateLimits.get(rateLimitKey);
            if (lastSendTime != null && System.currentTimeMillis() - lastSendTime < SEND_INTERVAL_SECONDS * 1000) {
                logger.warn("邮件发送过于频繁，邮箱: {}", normEmail);
                return false;
            }
            
            // 生成验证码
            String code = generateVerificationCode();
            
            // 先存储验证码到内存（确保发送前已存储）
            String codeKey = "email_code:" + normEmail;
            verificationCodes.put(codeKey, code);
            logger.info("验证码已存储 - 邮箱: {}, codeKey: {}, 验证码: {}", normEmail, codeKey, code);
            
            // 发送邮件
            boolean success = sendEmail(normEmail, code);
            if (success) {
                // 设置发送频率限制
                rateLimits.put(rateLimitKey, System.currentTimeMillis());
                
                // 设置验证码过期时间
                scheduler.schedule(() -> {
                    verificationCodes.remove(codeKey);
                    logger.info("验证码已过期，邮箱: {}", normEmail);
                }, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
                
                logger.info("邮件验证码发送成功，邮箱: {}, 验证码: {}", normEmail, code);
                return true;
            } else {
                // 发送失败，移除已存储的验证码
                verificationCodes.remove(codeKey);
                logger.warn("邮件发送失败，已移除验证码，邮箱: {}", normEmail);
            }
            
        } catch (Exception e) {
            logger.error("发送邮件验证码失败，邮箱: {}", email, e);
        }
        
        return false;
    }
    
    
    /**
     * 验证邮件验证码
     */
    public boolean verifyEmailCode(String email, String code) {
        try {
            String normEmail = normalizeEmail(email);
            String codeKey = "email_code:" + normEmail;
            String storedCode = verificationCodes.get(codeKey);
            
            logger.info("验证码验证调试 - 邮箱: {}, codeKey: {}, 存储码: {}, 输入码: {}", 
                normEmail, codeKey, storedCode, code);

            if (storedCode != null && storedCode.equals(code)) {
                // 验证成功后删除验证码
                verificationCodes.remove(codeKey);
                logger.info("邮件验证码验证成功，邮箱: {}", normEmail);
                return true;
            }

            logger.warn("邮件验证码验证失败，邮箱: {}, 输入码: {}, 存储码: {}", normEmail, code, storedCode);
            return false;
            
        } catch (Exception e) {
            logger.error("验证邮件验证码失败，邮箱: {}", email, e);
            return false;
        }
    }
    
    /**
     * 获取验证码（仅用于开发模式返回给前端）
     */
    public String getVerificationCode(String email) {
        String normEmail = normalizeEmail(email);
        String codeKey = "email_code:" + normEmail;
        return verificationCodes.get(codeKey);
    }
    
    /**
     * 开发模式：直接设置验证码（仅开发环境使用）
     */
    public void setVerificationCode(String email, String code) {
        String normEmail = normalizeEmail(email);
        String codeKey = "email_code:" + normEmail;
        verificationCodes.put(codeKey, code);

        // 设置验证码过期时间
        scheduler.schedule(() -> {
            verificationCodes.remove(codeKey);
            logger.info("开发模式验证码已过期，邮箱: {}", normEmail);
        }, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);

        logger.info("开发模式验证码设置成功，邮箱: {}, 验证码: {}", normEmail, code);
    }
    
    
    /**
     * 发送邮件（使用腾讯云SES邮件推送服务）
     */
    private boolean sendEmail(String email, String code) {
        try {
            // 记录当前模板ID配置
            logger.info("当前邮件模板ID配置: {}", templateId);
            
            // 如果没有配置模板ID，使用开发模式（仅记录日志）
            if (templateId == null || templateId == 0) {
                logger.warn("未配置邮件模板ID，使用开发模式。验证码: {}, 邮箱: {}", code, email);
                logger.info("开发模式：邮件验证码发送到: {}, 验证码: {}", email, code);
                return true; // 开发模式下返回成功
            }
            
            logger.info("使用生产模式发送邮件，收件人: {}, 模板ID: {}", email, templateId);
            
            // 使用腾讯云SES发送邮件
            boolean success = tencentSesMailService.sendVerificationCodeEmail(email, code, templateId);
            
            if (success) {
                logger.info("邮件验证码发送成功，邮箱: {}", email);
            } else {
                logger.error("邮件验证码发送失败，邮箱: {}", email);
                logger.error("可能的原因：");
                logger.error("1. SES权限未配置（检查CAM权限策略）");
                logger.error("2. 发信地址未验证（检查SES控制台）");
                logger.error("3. 模板ID错误（当前模板ID: {}）", templateId);
                logger.error("详细排查指南请参考: TENCENT_SES_PERMISSION_FIX.md");
            }
            
            return success;
            
        } catch (Exception e) {
            logger.error("邮件发送异常，邮箱: {}, 错误: {}", email, e.getMessage(), e);
            return false;
        }
    }
}
