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;
    
    // 使用内存存储验证码
    private final ConcurrentHashMap<String, String> verificationCodes = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Long> rateLimits = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    
    /**
     * 验证码长度
     */
    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 rateLimitKey = "email_rate_limit:" + email;
            Long lastSendTime = rateLimits.get(rateLimitKey);
            if (lastSendTime != null && System.currentTimeMillis() - lastSendTime < SEND_INTERVAL_SECONDS * 1000) {
                logger.warn("邮件发送过于频繁，邮箱: {}", email);
                return false;
            }
            
            // 生成验证码
            String code = generateVerificationCode();
            
            // 发送邮件
            boolean success = sendEmail(email, code);
            if (success) {
                // 存储验证码到内存
                String codeKey = "email_code:" + email;
                verificationCodes.put(codeKey, code);
                
                // 设置发送频率限制
                rateLimits.put(rateLimitKey, System.currentTimeMillis());
                
                // 设置验证码过期时间
                scheduler.schedule(() -> {
                    verificationCodes.remove(codeKey);
                    logger.info("验证码已过期，邮箱: {}", email);
                }, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
                
                logger.info("邮件验证码发送成功，邮箱: {}", email);
                return true;
            }
            
        } catch (Exception e) {
            logger.error("发送邮件验证码失败，邮箱: {}", email, e);
        }
        
        return false;
    }
    
    
    /**
     * 验证邮件验证码
     */
    public boolean verifyEmailCode(String email, String code) {
        try {
            String codeKey = "email_code:" + email;
            String storedCode = verificationCodes.get(codeKey);
            
            if (storedCode != null && storedCode.equals(code)) {
                // 验证成功后删除验证码
                verificationCodes.remove(codeKey);
                logger.info("邮件验证码验证成功，邮箱: {}", email);
                return true;
            }
            
            logger.warn("邮件验证码验证失败，邮箱: {}, 输入码: {}", email, code);
            return false;
            
        } catch (Exception e) {
            logger.error("验证邮件验证码失败，邮箱: {}", email, e);
            return false;
        }
    }
    
    /**
     * 开发模式：直接设置验证码（仅开发环境使用）
     */
    public void setVerificationCode(String email, String code) {
        String codeKey = "email_code:" + email;
        verificationCodes.put(codeKey, code);
        
        // 设置验证码过期时间
        scheduler.schedule(() -> {
            verificationCodes.remove(codeKey);
            logger.info("开发模式验证码已过期，邮箱: {}", email);
        }, CODE_EXPIRE_MINUTES, TimeUnit.MINUTES);
        
        logger.info("开发模式验证码设置成功，邮箱: {}, 验证码: {}", email, code);
    }
    
    
    /**
     * 发送邮件（使用腾讯云SES邮件推送服务）
     */
    private boolean sendEmail(String email, String code) {
        try {
            // 如果没有配置模板ID，使用开发模式（仅记录日志）
            if (templateId == null || templateId == 0) {
                logger.warn("未配置邮件模板ID，使用开发模式。验证码: {}, 邮箱: {}", code, email);
                logger.info("开发模式：邮件验证码发送到: {}, 验证码: {}", email, code);
                return true; // 开发模式下返回成功
            }
            
            // 使用腾讯云SES发送邮件
            boolean success = tencentSesMailService.sendVerificationCodeEmail(email, code, templateId);
            
            if (success) {
                logger.info("邮件验证码发送成功，邮箱: {}", email);
            } else {
                logger.error("邮件验证码发送失败，邮箱: {}", email);
            }
            
            return success;
            
        } catch (Exception e) {
            logger.error("邮件发送异常，邮箱: {}", email, e);
            return false;
        }
    }
}
