package com.slodon.b2b2c.model.msg;

import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.beust.jcommander.ParameterException;
import com.slodon.b2b2c.core.config.DomainUrlUtil;
import com.slodon.b2b2c.core.constant.SMSConst;
import com.slodon.b2b2c.core.exception.MallException;
import com.slodon.b2b2c.core.sms.SmsRequest;
import com.slodon.b2b2c.core.sms.SmsResponse;
import com.slodon.b2b2c.core.util.StringUtil;
import com.slodon.b2b2c.sms.TencentSmsSender;
import com.slodon.b2b2c.sms.YunPianSmsSender;
import com.slodon.b2b2c.sms.base.SmsSender;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 消息发送model层
 */
@Slf4j
@Component
public class MsgSendModel {

    //创建一个线程池
    private ExecutorService pool = Executors.newFixedThreadPool(SMSConst.DEFAULT_RUN_THREAD_NUM);

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 发送验证码短信
     *
     * @param mobile 手机号
     * @return
     */
    @SneakyThrows
    public SmsResponse sendVerifyCode(String mobile) {
        if (StringUtil.isEmpty(mobile)) {
            throw new MallException("请指定要发送的手机号码");
        }
        SmsRequest smsRequest = new SmsRequest();
        smsRequest.setSmsType(SMSConst.VERIFY_SMS);
        smsRequest.setMobile(mobile);

        SmsResponse smsResponse = null;
        try {
            if (pool.isShutdown()) {
                pool = Executors.newFixedThreadPool(SMSConst.DEFAULT_RUN_THREAD_NUM);
            }
            smsResponse = (SmsResponse) pool.submit(new SMSCall(smsRequest)).get();
        } catch (Exception e) {
            log.error("[MsgSendModel][sendVerifyCode]发送验证码短信异常:", e);
            //关闭线程池
            pool.shutdown();
        }
        return smsResponse;
    }

    /**
     * 发送通知短信
     *
     * @param smsRequest
     */
    public void sendSMS(SmsRequest smsRequest) {
        if (StringUtil.isEmpty(smsRequest.getMobile())) {
            throw new MallException("请指定要发送的手机号码");
        }
        new Thread(new SMSThread(smsRequest)).start();
    }


    /**
     * 发送邮件
     *
     * @param toAddress 邮件接收地址
     * @param subject   主题
     * @param content   内容
     */
    public void sendMail(String toAddress, String subject, String content) {
        MailAccount account = new MailAccount();
        account.setHost(stringRedisTemplate.opsForValue().get("notification_email_smtp_host"));
        account.setPort(Integer.parseInt(stringRedisTemplate.opsForValue().get("notification_email_smtp_port")));
        account.setFrom(stringRedisTemplate.opsForValue().get("notification_email_sender_address"));
        account.setUser(stringRedisTemplate.opsForValue().get("notification_email_sender_name"));
        account.setPass(stringRedisTemplate.opsForValue().get("notification_email_sender_password"));
        account.setAuth(true);
        account.setStarttlsEnable(true);
        account.setSslEnable(true);
        account.setDebug(true);
        MailUtil.send(account, toAddress, subject, content, false);
    }

    class SMSCall implements Callable<Object> {

        private SmsRequest smsRequest;

        SMSCall(SmsRequest smsRequest) {
            this.smsRequest = smsRequest;
        }

        @Override
        public Object call() {
            //根据系统配置的发送方式，获取短信发送对象
            SmsSender smsSender;
            switch (DomainUrlUtil.SEND_SMS_TYPE) {
                case 1:
                    //腾讯云发送
                    smsSender = new TencentSmsSender(stringRedisTemplate);
                    break;
                case 2:
                    //云片发送
                    smsSender = new YunPianSmsSender(stringRedisTemplate);
                    break;
                default:
                    throw new MallException("参数错误");
            }
            return smsSender.sendSms(smsRequest);
        }
    }

    class SMSThread implements Runnable {

        private SmsRequest smsRequest;

        SMSThread(SmsRequest smsRequest) {
            this.smsRequest = smsRequest;
        }

        @Override
        public void run() {
            //根据系统配置的发送方式，获取短信发送对象
            SmsSender smsSender;
            switch (DomainUrlUtil.SEND_SMS_TYPE) {
                case 1:
                    //腾讯云发送
                    smsSender = new TencentSmsSender(stringRedisTemplate);
                    break;
                case 2:
                    //云片发送
                    smsSender = new YunPianSmsSender(stringRedisTemplate);
                    break;
                default:
                    throw new ParameterException("参数错误");
            }
            smsSender.sendSms(smsRequest);
        }
    }

}
