package com.qnfhq.utils;

import com.qnfhq.common.redis.RedisUtils;
import com.qnfhq.common.utils.SpringContextUtils;
import com.qnfhq.constant.ApiConstant;
import com.qnfhq.modules.user.dto.setting.EmailSetting;
import com.qnfhq.modules.user.enums.CachePrefix;
import com.qnfhq.modules.user.enums.UserCodeTypeEnum;
import com.qnfhq.modules.user.service.impl.AppUserServiceImpl;
import com.qnfhq.utils.sms.SmsSenderUtil;
import com.sun.mail.util.MailSSLSocketFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import jakarta.mail.*;
import jakarta.mail.internet.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @packageName:com.zebra.common.utils
 * @className:EmailUtils
 * @description:邮箱工具类
 * @version:1.0.0
 * @author:xuanyihun
 * @createDate:2022-05-06 11:07
 */
@Slf4j
public class EmailUtils {



    private static List<EmailSetting> emailSettingList = new ArrayList<EmailSetting>(){
        {
            add(new EmailSetting("bindCodeEmail.ftl","ADAE","adae@bnccy.top","uI7aE5qX1nU7oS3f","smtpdm.aliyun.com","465"));
            add(new EmailSetting("bindCodeEmail.ftl","ADAE","adae@plaids.top","fS0iS2pH2iG2aS9c","smtpdm.aliyun.com","465"));

        }
    };

    /**
     * 随机方案
     */
    private static final Random RANDOM = new Random();


    /**
     * @description 验证邮箱
     * @param email(邮箱)
     * @version 1.0.0
     * @author xuanyihun
     * @createDate 2022-05-06 11:23
     * @return boolean
    */
    public static boolean checkEmail(String email) {

        boolean flag = false;
        try {
            String check = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
            Pattern regex = Pattern.compile(check);
            Matcher matcher = regex.matcher(email);
            flag = matcher.matches();
        } catch (Exception exception) {
            flag = false;
        }
        return flag;

    }




    public static void formMail(String email,String type) throws Exception {
        RedisUtils redisUtils = SpringContextUtils.getBean(RedisUtils.class);
//        SettingService settingService = SpringContextUtils.getBean(SettingService.class);
        String randomCode = String.valueOf(SmsSenderUtil.getRandomNumber(100000, 999999));
        AppUserServiceImpl bean = SpringContextUtils.getBean(AppUserServiceImpl.class);
        int index = RANDOM.nextInt(emailSettingList.size());
        System.out.println("邮箱随机发送:" + index);
        EmailSetting emailSetting =  emailSettingList.get(index);
        /**
        Setting setting = settingService.get(SettingEnum.EMAIL_SETTING.name());
        EmailSetting emailSetting = JSONUtil.toBean(setting.getSettingValue(), EmailSetting.class);
         **/
        String appName = emailSetting.getMailAppName();
        String host = emailSetting.getMailHost();
        String port = emailSetting.getMailPort();
        String username = emailSetting.getMailUsername();
        String password = emailSetting.getMailPassword();
        String templateCode = emailSetting.getMailTemplate();


        // 1.创建连接对象javax.mail.Session
        // 2.创建邮件对象 javax.mail.Message
        // 3.发送一封激活邮件
        Properties properties = System.getProperties();// 获取系统属性

        properties.setProperty("mail.smtp.host", host);// 设置邮件服务器
        properties.setProperty("mail.transport.protocol","smtp");
        properties.setProperty("mail.smtp.port", port);  //不需要 默认端口
        properties.setProperty("mail.smtp.auth", "true");// 打开认证
        //  properties.put("mail.smtp.socketFactory", "javax.net.ssl.SSLSocketFactory");
        try {
            // QQ邮箱需要下面这段代码，163邮箱不需要
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            properties.put("mail.smtp.ssl.enable", "true");
            properties.put("mail.smtp.ssl.socketFactory", sf);
            properties.put("mail.smtp.ssl.protocols", "TLSv1.2"); //加上这句解决问题

            // 1.获取默认session对象
            Session session = Session.getInstance(properties, new Authenticator() {
                @Override
                public PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(username, password);
                }
            });

          //  session.setDebug(true);

            //2、通过session得到transport对象
            Transport transport = session.getTransport();
            //3、使用用户名和授权码连上邮件服务器
            transport.connect(host,username,password);


            // 4.创建邮件对象
            Message message = new MimeMessage(session);
            // 4.1设置发件人
            message.setFrom(new InternetAddress(username));
            // 4.2设置接收人
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
            // 4.3设置邮件主题
            String title = appName;
            message.setSubject(title);

            Map<String, Object> model = new HashMap<>(16);
            model.put("code", randomCode);
            Configuration cfg = new Configuration(Configuration.VERSION_2_3_26);
            cfg.setClassForTemplateLoading(bean.getClass(), "/templates");
            Template template = cfg.getTemplate(templateCode);
            String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
            // 2.4设置邮件内容
            message.setContent(html, "text/html;charset=UTF-8");
            //5、发送邮件
            transport.sendMessage(message,message.getAllRecipients());
            //6、关闭连接
            transport.close();
        } catch (Exception e) {

            log.error("===================================发送邮箱报错==================================={}",e.getMessage());
            throw new Exception(e.getMessage());
        }

        //绑定邮箱 5分钟
        final String emailKey = String.format("%s%s%s",CachePrefix.EMAIL_CODE.getPrefix(),UserCodeTypeEnum.valueOf(type),email);
        redisUtils.set(emailKey, randomCode, ApiConstant.EMAIL_EXPIRE);
        final String codeTryKey = String.format("%s%s", emailKey,"try");
        redisUtils.delete(codeTryKey);
    }



}
