package com.jeesharp.business.modules.member.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.jeesharp.business.modules.member.service.EmailCodeService;
import com.jeesharp.framework.constant.basecache.SysCacheConstant;
import com.jeesharp.framework.mail.core.EmailSendResult;
import com.jeesharp.framework.mail.service.EmailGatewayService;
import com.jeesharp.framework.utils.base.ExceptionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * 邮件验证码服务实现
 * 验证码存储于 Redis，通过邮件网关（jeesharp-spring-boot-starter-mail）发送
 *
 * @author jeesharp
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EmailCodeServiceImpl implements EmailCodeService {

    private static final int CODE_LENGTH = 6;
    private static final int EXPIRE_SECONDS = 300;

    private final StringRedisTemplate redisTemplate;
    private final EmailGatewayService emailGatewayService;

    @Override
    public int sendCode(String email, String scene) {
        if (StrUtil.isBlank(email) || StrUtil.isBlank(scene)) {
            ExceptionUtil.error("邮箱和场景不能为空");
        }
        String code = RandomUtil.randomNumbers(CODE_LENGTH);
        String key = buildKey(email, scene);
        redisTemplate.opsForValue().set(key, code, EXPIRE_SECONDS, TimeUnit.SECONDS);
        log.info("邮件验证码已生成: email={}, scene={}, expireSeconds={}", email, scene, EXPIRE_SECONDS);

        String subject = resolveSubject(scene);
        String content = String.format("您的验证码是：%s，%d分钟内有效，请勿泄露。", code, EXPIRE_SECONDS / 60);
        EmailSendResult result = emailGatewayService.send(
                Collections.singletonList(email),
                subject,
                content,
                false
        );
        if (!result.isSuccess()) {
            log.warn("邮件验证码发送失败: email={}, scene={}, msg={}", email, scene, result.getFailReason());
            ExceptionUtil.error("验证码发送失败，请稍后重试");
        }
        return EXPIRE_SECONDS;
    }

    @Override
    public boolean verify(String email, String scene, String emailCode) {
        if (StrUtil.isBlank(email) || StrUtil.isBlank(scene) || StrUtil.isBlank(emailCode)) {
            return false;
        }
        String key = buildKey(email, scene);
        String cached = redisTemplate.opsForValue().get(key);
        return emailCode.equals(cached);
    }

    @Override
    public boolean verifyAndRemove(String email, String scene, String emailCode) {
        if (!verify(email, scene, emailCode)) {
            return false;
        }
        String key = buildKey(email, scene);
        redisTemplate.delete(key);
        return true;
    }

    private String buildKey(String email, String scene) {
        return SysCacheConstant.MOBILE_EMAIL_REDIS_PREFIX + ":" + scene.toLowerCase() + ":" + email.toLowerCase();
    }

    private String resolveSubject(String scene) {
        return switch (scene.toUpperCase()) {
            case "LOGIN" -> "登录验证码";
            case "REGISTER" -> "注册验证码";
            case "RESET_PWD" -> "重置密码验证码";
            case "BIND" -> "绑定邮箱验证码";
            default -> "验证码";
        };
    }
}
