package com.patzn.lims.sys.service.impl;

import com.baomidou.kisso.common.IpHelper;
import com.baomidou.kisso.common.util.RandomUtil;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.toolkit.FreemarkerUtils;
import com.patzn.lims.core.toolkit.RegexUtils;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.sys.enums.VerificationCodeEnum;
import com.patzn.lims.sys.service.IEmailService;
import com.patzn.lims.sys.service.ISysUserService;
import com.patzn.lims.sys.service.RedisCountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class EmailServiceImpl implements IEmailService {

    private static final Logger logger = LoggerFactory.getLogger(EmailServiceImpl.class);

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private RedisCountService redisCountService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private JavaMailSenderImpl mailSender;

    @Override
    public boolean sendValidCode(HttpServletRequest request, Account account, String email) {
        // 同模块同一个 IP 一小时允许 100 次请求验证码
        String redisKey = "emailCode" + IpHelper.getIpAddr(request);
        int ipCount = redisCountService.get(redisKey);
        PtAssert.fail(ipCount >= 100, "当前 IP 发送次数过多 1 小时候后重试");
        PtAssert.fail(!RegexUtils.isEmail(email), "请输入正确的邮箱地址");
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setFrom(mailSender.getUsername(), "帕特云");
            mimeMessageHelper.setSubject("帕特智能云邮箱绑定");
            Map model = new HashMap(2);
            model.put("username", account.getUserName());
            String code = RandomUtil.getNumber(6);
            model.put("code", code);

            // 记录 1 小时 IP 发送次数
            redisCountService.set(redisKey, ipCount, 1);

            // 记录 code email 关联
            redisTemplate.opsForValue().set(VerificationCodeEnum.BIND_EMAIL.getKey(account.getUserIdStr(), code), email, 30, TimeUnit.MINUTES);
            mimeMessageHelper.setText(FreemarkerUtils.emailTpl("bind", model), true);
            logger.info(String.format("发送邮件：%s 验证码：%s", email, code));
            mailSender.send(mimeMessage);
        } catch (Exception e) {
            logger.error(String.format("邮件：%s 发送异常", email), e);
            return false;
        }
        return true;
    }


    @Override
    public boolean bindByCode(Account account, String vailCode) {
        if (null == account || null == vailCode) {
            return false;
        }
        // 绑定激活邮箱验证
        String email = redisTemplate.opsForValue().get(VerificationCodeEnum.BIND_EMAIL.getKey(account.getUserIdStr(), vailCode));
        PtAssert.fail(null == email, "该验证码无效，请重新输入");
        return sysUserService.bindEmailById(account.getUserId(), email);
    }

}
