package com.citygis.web.service.impl;

import cn.hutool.extra.mail.MailUtil;
import com.citygis.common.core.domain.AjaxResult;
import com.citygis.web.domain.Mail;
import com.citygis.web.service.MailService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @Author: zyl
 * @CreateTime: 2024-12-25
 * @Description: 邮箱 服务实现类
 * @Version: 1.0
 */
@Service
public class MailServiceImpl implements MailService {

    @Resource
    RedisTemplate redisTemplate;

    /**
     * 发送邮件的方法，用于发送包含验证码的邮件。
     *
     * @param mail 包含收件人邮箱地址的Mail对象
     * @return 返回一个AjaxResult对象，表示邮件发送的结果
     */
    @Override

    public AjaxResult sendMail(Mail mail) {
        // 检查Redis中是否存在该收件人的验证码
        if (redisTemplate.hasKey(mail.getToMail())) {
            return AjaxResult.success("验证码已发送，请不要重复发送");
        }

        // 获取收件人的邮箱地址
        String toMail = mail.getToMail();

        try {
            // 生成验证码并保存到变量中
            String code = generateVerificationCode();

            // 构建邮件的HTML内容
            String htmlContent = buildHtmlContent(code);

            // 发送邮件
            MailUtil.send(toMail, "登录验证码", htmlContent, true);

            // 将验证码存储到Redis中，设置有效期为1分钟
            storeVerificationCodeInRedis(toMail, code);

            // 返回成功结果
            return AjaxResult.success("验证码已发送至您的邮箱: " + toMail);

        } catch (Exception e) {
            // 捕获异常并记录错误信息
            return AjaxResult.error("邮件发送失败=====>" + e.getMessage());
        }
    }

    // 提取生成HTML邮件内容的逻辑
    private String buildHtmlContent(String code) {
        return "<!DOCTYPE html>" +
                "<html lang=\"zh-CN\">" +
                "<head>" +
                "    <meta charset=\"UTF-8\">" +
                "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" +
                "    <title>验证码邮件</title>" +
                "    <style>" +
                "        body {" +
                "            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;" +
                "            background-color: #f7f7f7;" +
                "            margin: 0;" +
                "            padding: 0;" +
                "        }" +
                "        .container {" +
                "            width: 100%;" +
                "            max-width: 600px;" +
                "            margin: 40px auto;" +
                "            background: #ffffff;" +
                "            border-radius: 10px;" +
                "            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);" +
                "            padding: 30px;" +
                "            text-align: center;" +
                "        }" +
                "        h1 {" +
                "            color: #333333;" +
                "            font-size: 28px;" +
                "            margin-bottom: 20px;" +
                "            font-weight: 600;" +
                "        }" +
                "        p {" +
                "            font-size: 16px;" +
                "            color: #666666;" +
                "            line-height: 1.6;" +
                "            margin-bottom: 15px;" +
                "        }" +
                "        .code {" +
                "            display: inline-block;" +
                "            padding: 15px 30px;" +
                "            font-size: 22px;" +
                "            font-weight: bold; color: #ffffff;" +
                "            background: linear-gradient(45deg, #6a11cb, #2575fc);" +
                "            border-radius: 8px;" +
                "            margin: 15px 0;" +
                "            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);" +
                "        }" +
                "        .info {" +
                "            background-color: #f9f9f9;" +
                "            border-left: 5px solid #6a11cb;" +
                "            padding: 10px 20px;" +
                "            font-size: 14px;" +
                "            color: #444444;" +
                "            margin-bottom: 25px;" +
                "        }" +
                "        .footer {" +
                "            font-size: 14px;" +
                "            color: #999999;" +
                "            margin-top: 30px;" +
                "            border-top: 1px solid #e1e1e1;" +
                "            padding-top: 15px;" +
                "        }" +
                "        .footer a {" +
                "            color: #2575fc;" +
                "            text-decoration: none;" +
                "        }" +
                "        .footer a:hover {" +
                "            text-decoration: underline;" +
                "        }" +
                "           </style>" +
                "</head>" +
                "<body>" +
                "    <div class=\"container\">" +
                "        <h1>六统一邮件</h1>" +
                "        <p>亲爱的用户，您好！</p>" +
                "        <p>为了保护您的账户安全，我们为您生成了以下验证码：</p>" +
                "        <div class=\"code\">"+code+"</div>" +
                "        <p class=\"info\">请在 <strong>1分钟</strong> 内输入验证码，验证码仅限本次使用。</p>" +
                "        <div class=\"footer\">" +
                "            <p>感谢您的支持！</p>" +
                "            <p>如果不是您本人操作，请忽略此邮件。</p>" +
                "        </div>" +
                "    </div>" +
                "</body>" +
                "</html>";
    }

    // 提取Redis存储验证码的逻辑
    private void storeVerificationCodeInRedis(String toMail, String code) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(toMail, code, 1, TimeUnit.MINUTES);  // 验证码存储1分钟
    }

    /**
     * 验证邮件验证码的方法。
     *
     * @param mail 包含收件人邮箱和验证码的邮件对象
     * @return 返回验证结果，成功或失败
     */
    @Override
    public AjaxResult verifyMail(Mail mail) {
        // Redis中存储验证码的Key
        String redisKey = mail.getToMail();

        // 检查Redis中是否存在该收件人的验证码
        if (!redisTemplate.hasKey(redisKey)) {
            // 如果Redis中没有该收件人的验证码，返回过期结果
            return AjaxResult.error("验证码已过期");
        }

        // 从Redis中获取验证码
        String rCode = (String) redisTemplate.opsForValue().get(redisKey);

        // 如果验证码为空或用户提供的验证码为空，返回验证失败
        if (rCode == null || mail.getCode() == null) {
            return AjaxResult.error("验证码验证失败");
        }

        // 比较用户提供的验证码和Redis中的验证码
        if (mail.getCode().equals(rCode)) {
            // 验证成功，立即删除Redis中的验证码
            redisTemplate.delete(redisKey);
            // 返回成功结果
            return AjaxResult.success("验证码验证成功");
        }

        // 验证码错误，返回失败结果
        return AjaxResult.error("验证码验证失败");
    }

    // 生成验证码
    public String generateVerificationCode() {
        Random random = new Random();
        int code = 100000 + random.nextInt(900000);  // 生成一个6位验证码
        return String.valueOf(code);
    }
}
