package com.ema.admin.modules.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ema.admin.modules.system.entity.SysDictData;
import com.ema.admin.modules.system.service.SysDictDataService;
import com.ema.admin.modules.system.service.SysEmailService;
import com.ema.common.consts.CommonConst;
import com.ema.common.exceptions.MyAssert;
import com.ema.common.tools.email.EmailService;
import com.ema.common.tools.redis.RedisService;
import com.ema.common.utils.CodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * 邮件服务实现
 */
@Slf4j
@Service
public class SysEmailServiceImpl implements SysEmailService {

    @Resource
    private RedisService redisService;
    @Resource
    private EmailService emailService;
    @Resource
    private SysDictDataService sysDictDataService;
    @Resource(name = CommonConst.ASYNC_POOL)
    private ThreadPoolTaskExecutor threadPoolExecutor;

    /**
     * 验证码缓存key前缀
     */
    private static final String EMAIL_CODE_PREFIX = "email:code";

    /**
     * 验证码有效期（分钟）
     */
    private static final long CODE_EXPIRE_MINUTES = 15;

    /**
     * 验证码长度
     */
    private static final int CODE_LENGTH = 6;

    @Override
    public void sendCode(String dictTypeCode, String dictCode, String email) {
        // 生成6位随机验证码
        String code = CodeUtil.getCode(CODE_LENGTH);
        // 缓存验证码到Redis，有效期15分钟
        redisService.set(EMAIL_CODE_PREFIX, email, code, CODE_EXPIRE_MINUTES * 60);

        SysDictData dictData = sysDictDataService.getByCode(dictTypeCode, dictCode);
        MyAssert.notNull(dictData, "数据模板不存在");

        threadPoolExecutor.execute(() -> {
            Map<String, Object> map = new HashMap<>();
            map.put("code", code);
            map.put("expireTime", CODE_EXPIRE_MINUTES + "分钟");
            String content = StrUtil.format(dictData.getValue(), map);
            emailService.sendText(email, dictData.getRemark(), content);
        });
    }

    @Override
    public void verifyCode(String email, String code) {
        String cachedCode = redisService.getStr(EMAIL_CODE_PREFIX, email);
        MyAssert.isTrue(StrUtil.isNotBlank(cachedCode), "验证码已过期或不存在，请重新获取！");
        MyAssert.isTrue(StrUtil.equalsIgnoreCase(cachedCode, code), "验证码不正确，请重新输入！");
        redisService.delete(EMAIL_CODE_PREFIX, email);
    }

}
