package com.vetti.common.service.verification.impl;

import com.vetti.common.config.TwilioConfig;
import com.vetti.common.config.VerificationEmailConfig;
import com.vetti.common.constant.CacheConstants;
import com.vetti.common.core.domain.R;
import com.vetti.common.core.redis.RedisCache;
import com.vetti.common.entity.verification.BaseTemplateEmail;
import com.vetti.common.entity.verification.RoutezVerificationCodeTemplate;
import com.vetti.common.exception.ServiceException;
import com.vetti.common.service.verification.VerificationService;
import com.vetti.common.utils.MessageUtils;
import com.vetti.common.utils.email.EmailUtil;
import com.vetti.common.utils.sms.TwilioSmsUtil;
import org.springframework.stereotype.Service;

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

/**
 * @author ID
 * @date 2025/9/4 16:49
 */
@Service
public class VerificationServiceImpl implements VerificationService {

    @Resource
    private TwilioConfig twilioConfig;

    @Resource
    private VerificationEmailConfig verificationConfig;

    @Resource
    private EmailUtil emailUtil;

    @Resource
    private TwilioSmsUtil twilioSmsUtil;

    @Resource
    private RedisCache redisCache;


    /**
     * 发送邮箱验证码（内容走的配置文件）
     *
     * @param email 收件人邮箱
     * @return
     */
    @Override
    public boolean sendVerificationCode(String email) {
        String code = generateVerificationCode();
        return sendVerificationCode(email, MessageUtils.messageCustomize("VerificationEmailTiTle"),
                MessageUtils.messageCustomize("VerificationEmailContent"), code);

    }

    /**
     * 发动邮箱验证码 （内容走的官网 配置好的模板）
     *
     * @param email 收件人邮箱
     * @return
     */
    @Override
    public boolean sendVerificationRoutezVerificationCode(String email) {
        String code = generateVerificationCode();
        RoutezVerificationCodeTemplate template = new RoutezVerificationCodeTemplate();
        template.setVerification_code(code);
        template.setVerification_expiration(verificationConfig.getExpirationMinutes());
        return sendTemplateCode(email,code,
                twilioConfig.getTemplateIds().getRoutezVerificationCode(), template);
    }

    /**
     * 使用 em7941.routez.app 域名发送验证码（官网模板）
     */
    @Override
    public void sendVerificationEm7941VerificationCode(String email) {
        String code = generateVerificationCode();
        RoutezVerificationCodeTemplate template = new RoutezVerificationCodeTemplate();
        template.setVerification_code(code);
        template.setVerification_expiration(verificationConfig.getExpirationMinutes());
        try {
            redisCache.setCacheObject(CacheConstants.VERIFICATION_EMAIL_CODE_KEY + email, code,
                    verificationConfig.getExpirationMinutes(), TimeUnit.MINUTES);
            emailUtil.sendEmailByEm7941(email, twilioConfig.getTemplateIds().getRoutezVerificationCode(), template);
        } catch (Exception e) {
            // 记录日志
            throw new ServiceException(MessageUtils.messageCustomize("systemVerificationEmailController10002"));
        }
    }

    /**
     * 发动邮箱验证码 （内容走的官网配置模板）
     *
     * @param email         收件人邮箱
     * @param code 验证码
     * @param templateId    官网模板ID
     * @param templateEmail 模板参数实体
     * @return
     */
    @Override
    public boolean sendTemplateCode(String email,String code, String templateId, BaseTemplateEmail templateEmail) {
        try {
            redisCache.setCacheObject(CacheConstants.VERIFICATION_EMAIL_CODE_KEY + email, code,
                    verificationConfig.getExpirationMinutes(), TimeUnit.MINUTES);
            emailUtil.sendEmail(email, templateId, templateEmail);
            return true;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 发送面试邀请邮件 （内容走的官网配置模板）
     *
     * @param email         收件人邮箱
     * @param templateId    官网模板ID
     * @param templateEmail 模板参数实体
     * @return
     */
    @Override
    public boolean sendInterviewTemplate(String email,String templateId, BaseTemplateEmail templateEmail) {
        try {
            emailUtil.sendEmail(email, templateId, templateEmail);
            return true;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 验证验证码是否有效
     *
     * @param email 收件人邮箱
     * @param code
     * @return
     */
    @Override
    public boolean verifyCode(String email, String code) {
        String codeR = redisCache.getCacheObject(CacheConstants.VERIFICATION_EMAIL_CODE_KEY + email);
        if (codeR == null) {//过期
            throw new ServiceException(MessageUtils.messageCustomize("systemVerificationEmailController10004"));
        }
        if (!code.equals(codeR)) {
            return false;
        }
        return true;
    }

    @Override
    public void sendPhoneVerificationCode(String phone){

        String code = generateVerificationCode();
        redisCache.setCacheObject(CacheConstants.VERIFICATION_EMAIL_CODE_KEY + phone, code,
                verificationConfig.getExpirationMinutes(), TimeUnit.MINUTES);
        String msg = "验证码为："+code;
        twilioSmsUtil.send(phone,msg);
    }


    private boolean sendVerificationCode(String email, String subject, String content) {
        String code = generateVerificationCode();
        return sendVerificationCode(email, subject, content, code);
    }

    /**
     * 生成随机验证码
     */
    private String generateVerificationCode() {
        int length = verificationConfig.getLength();
        StringBuilder codeBuilder = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            codeBuilder.append(random.nextInt(10));
        }
        return codeBuilder.toString();
    }

    private boolean sendVerificationCode(String email, String subject, String content, String code) {
        try {
            redisCache.setCacheObject(CacheConstants.VERIFICATION_EMAIL_CODE_KEY + email, code,
                    verificationConfig.getExpirationMinutes(), TimeUnit.MINUTES);
            emailUtil.sendEmail(email, subject, MessageFormat.format(content, code, verificationConfig.getExpirationMinutes()));
            return true;
        } catch (Exception e) {
            // 记录日志
            e.printStackTrace();
            return false;
        }
    }

}
