package com.trade.client.enterprise.customer.service.impl;

import com.trade.client.enterprise.customer.constant.CustConstant;
import com.trade.client.enterprise.customer.constant.RedisKey;
import com.trade.client.enterprise.customer.domain.CustomerUser;
import com.trade.client.enterprise.customer.enums.SmsCodeTypeEnum;
import com.trade.client.enterprise.customer.service.CustomerMessageService;
import com.trade.client.enterprise.customer.service.CustomerUserService;
import com.trade.common.constant.HttpStatus;
import com.trade.common.exception.ServiceException;
import com.trade.common.redis.RedisCache;
import com.trade.common.utils.DateUtils;
import com.trade.common.utils.RegexpUtil;
import com.trade.common.utils.StringUtils;
import com.trade.service.message.EmailTemplate;
import com.trade.service.message.impl.AliyunSmsSend;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

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

/**
 * @description:
 * @Author: wanglang
 * @Date: 2024/4/1 19:26
 * @Version: 1.0
 */
@Service
public class CustomerMessageServiceImpl implements CustomerMessageService {

    /**
     * 发送次数
     */
    @Value("${sms.sendCount}")
    private Long sendCount;
    /**
     * 验证码过期时间 单位分钟
     */
    @Value("${sms.verificationCodeExpired}")
    private Integer verificationCodeExpired;
    @Resource
    private AliyunSmsSend smsTemplate;
    @Resource
    private RedisCache redisCache;
    @Resource
    private EmailTemplate emailTemplate;
    @Resource
    private CustomerUserService customerUserService;

    @Override
    public boolean sendSms(String phoneNumber, String type) {
        if (phoneNumber == null) {
            throw new ServiceException("手机号不能为空", HttpStatus.BAD_REQUEST);
        }
        if (type == null) {
            throw new ServiceException("短信发送类型不能为空", HttpStatus.BAD_REQUEST);
        }
        if (!SmsCodeTypeEnum.REGISTER.getType().equals(type) && !SmsCodeTypeEnum.CHANGE_NEW.getType().equals(type)) {
            CustomerUser customerUser = customerUserService.findByPhoneOrName(phoneNumber);
            if (customerUser == null) {
                throw new ServiceException("该手机号未注册", HttpStatus.BAD_REQUEST);
            }
        }
        String smsSendCount = RedisKey.SMS_SEND_COUNT + phoneNumber;
        if (isSmsLimit(smsSendCount)) {
            throw new ServiceException("今日短信发送次数已超过限制", HttpStatus.BAD_REQUEST);
        }
        // todo 短信模板
        String templateCode = SmsCodeTypeEnum.getByType(type).getCode();
        String code = smsTemplate.send(phoneNumber, templateCode);
        // 验证码5有效时间
        redisCache.setCacheObject(RedisKey.VERIFICATION_CODE_EXPIRED + phoneNumber, code, verificationCodeExpired,
                TimeUnit.MINUTES);
        // 当天发送次数
        if (!redisCache.hasKey(smsSendCount)) {
            redisCache.increment(smsSendCount, 1L);
            // 设置过期时间
            redisCache.expireAt(smsSendCount, DateUtils.getLastTimeOfTheDay());
        } else {
            redisCache.increment(smsSendCount, 1L);
        }
        return true;
    }

    @Override
    public boolean sendEmail(String email, String templateName) {
        if (StringUtils.isEmpty(email)) {
            throw new ServiceException("邮件不能为空", HttpStatus.BAD_REQUEST);
        }
        if (!RegexpUtil.checkEmail(email)) {
            throw new ServiceException("邮箱格式不正确", HttpStatus.BAD_REQUEST);
        }
        if (StringUtils.isEmpty(templateName)) {
            templateName = CustConstant.USER_BINDING_EMAIL_TEMPLATE;
        }
        Map<String, Object> variables = new HashMap<>();
        String subject = null;
        switch (templateName) {
            case CustConstant.USER_BINDING_EMAIL_TEMPLATE:
                variables.put("verificationCode", smsTemplate.genCode());
                subject = CustConstant.USER_BINDING_EMAIL_SUBJECT;
                break;
            case CustConstant.USER_CERTIFICATION_TEMPLATE:
                variables.put("verificationCode", smsTemplate.genCode());
                subject = CustConstant.USER_CERTIFICATION_SUBJECT;
                break;
            default:
                break;
        }
        // 发送邮件
        emailTemplate.sendMailTemplate(subject, templateName, null, null, variables, null, null, new String[] {
                email
        });
        // 记录验证码
        if (templateName.equals(CustConstant.USER_BINDING_EMAIL_TEMPLATE)
                || templateName.equals(CustConstant.USER_CERTIFICATION_TEMPLATE)) {
            redisCache.setCacheObject(RedisKey.VERIFICATION_CODE_EXPIRED + templateName + ":" + email,
                    variables.get("verificationCode").toString(), 10, TimeUnit.MINUTES);
        }
        return true;
    }

    @Override
    public boolean checkEmailAuthCode(String email, String authCode, String templateName) {
        if (StringUtils.isEmpty(email)) {
            throw new ServiceException("邮件不能为空", HttpStatus.BAD_REQUEST);
        }
        if (StringUtils.isEmpty(authCode)) {
            throw new ServiceException("验证码不能为空", HttpStatus.BAD_REQUEST);
        }
        String redisKey = RedisKey.VERIFICATION_CODE_EXPIRED + templateName + ":" + email;
        if (Boolean.FALSE.equals(redisCache.hasKey(redisKey))) {
            throw new ServiceException("企业邮箱验证失败，无效验证码", HttpStatus.BAD_REQUEST);
        }
        if (!authCode.equals(redisCache.getCacheObject(redisKey))) {
            throw new ServiceException("企业邮箱验证失败，验证码有误", HttpStatus.BAD_REQUEST);
        }
        //redisCache.deleteObject(redisKey);
        return true;
    }

    /**
     * 是否超过当天短信记录
     *
     * @param key 手机号
     * @return true 超过限制 false 未超过限制
     */
    private boolean isSmsLimit(String key) {
        if (!redisCache.hasKey(key)) {
            return false;
        } else {
            long smsSendCount = Long.parseLong(redisCache.getCacheObject(key).toString());
            return smsSendCount >= sendCount;
        }
    }
}
