package com.ruoyi.ai.service;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.EmailUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.VerifyCodeUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.mail.MessagingException;
import java.util.concurrent.TimeUnit;

/**
 * 邮件验证码Service
 */
@Service
@RequiredArgsConstructor
public class EmailVerifyService {

    private final EmailUtils emailUtils;  // 邮箱发送工具类
    private final StringRedisTemplate redisTemplate;  // Redis操作模板

    // 从配置文件读取验证码配置
    @Value("${verify.code.length}")
    private int codeLength;  // 验证码长度
    @Value("${verify.code.expire}")
    private int expireSeconds;  // 验证码有效期（秒）
    @Value("${verify.code.prefix}")
    private String redisKeyPrefix;  // Redis存储前缀
    @Value("${verify.code.send-interval}")
    private int sendIntervalSeconds;  // 重复发送间隔（秒）

    /**
     * 发送邮件验证码
     * @param email 收件人邮箱
     * @throws MessagingException 邮件发送异常
     * @throws RuntimeException 重复发送/参数异常
     */
    public void sendVerifyCode(String email) throws MessagingException {
        // 1. 参数校验（邮箱格式）
        if (!StringUtils.hasText(email) || !email.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$")) {
            throw new ServiceException(MessageUtils.message("Email.user.email"));
        }

        // 2. 防止重复发送（检查Redis中是否存在未过期的发送记录）
        String sendKey = redisKeyPrefix + "send_" + email;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(sendKey))) {
            long remainingTime = redisTemplate.getExpire(sendKey, TimeUnit.SECONDS);
            throw new ServiceException(MessageUtils.message("email.code.sent", remainingTime));
        }

        // 3. 生成验证码（纯数字）
        String verifyCode = VerifyCodeUtils.generateNumberCode(codeLength);

        // 4. 存储验证码到Redis（设置过期时间）
        String codeKey = redisKeyPrefix + email;
        redisTemplate.opsForValue().set(codeKey, verifyCode, expireSeconds, TimeUnit.SECONDS);

        // 5. 发送邮件（纯文本/HTML）
        String subject = "【Code】";
        String content = MessageUtils.message(verifyCode, expireSeconds / 60);
        emailUtils.sendTextEmail(email, subject, content);

        // 6. 记录发送时间（设置重复发送间隔）
        redisTemplate.opsForValue().set(sendKey, "sent", sendIntervalSeconds, TimeUnit.SECONDS);
    }

    /**
     * 验证邮箱验证码
     * @param email 邮箱
     * @param inputCode 用户输入的验证码
     * @return true=验证通过，false=验证失败
     */
    public boolean verifyCode(String email, String inputCode) {
        // 1. 参数校验
        if (!StringUtils.hasText(email) || !StringUtils.hasText(inputCode)) {
            return false;
        }

        // 2. 从Redis获取存储的验证码
        String codeKey = redisKeyPrefix + email;
        String storedCode = redisTemplate.opsForValue().get(codeKey);

        // 3. 验证验证码（非空 + 相等）
        if (inputCode.equals(storedCode)) {
            // 验证通过后删除验证码（防止重复使用）
            redisTemplate.delete(codeKey);
            return true;
        }
        return false;
    }
}
