package com.gree.mall.miniapp.logic.common;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.ClientException;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gree.mall.miniapp.constant.Constant;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.plus.entity.SmsRecord;
import com.gree.mall.miniapp.plus.service.SmsRecordService;
import com.gree.mall.miniapp.utils.DateUtils;
import com.gree.mall.miniapp.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Slf4j
@Service
public class SMSLogic {

    @Autowired
    RedisUtil redisUtil;
    @Value("${spring.profiles.active}")
    private String active;

    private static String accessKeyId = "LTAI5tDHiEGKuwzNhW2gLPyc";
    private static String accessKeySecret = "NVXSx3Gj7fHv6unGwWgalJh49uMZOI";
    private static String SIGN_NAME = "售修宝";
    //短信验证码
    private static String TEMPLATE_SMS_CODE = "SMS_465295106";

    @PostConstruct
    public void init() {
        if (StringUtils.equals(active, "prdjx")) {
            accessKeyId = "LTAI5tBYgEPwxHyYeafvqJxW";
            accessKeySecret = "NRQyHnrYTx65HeMb1TaNKM7e8BTqVf";
            SIGN_NAME = "匠心服务社区";
            //短信验证码
            TEMPLATE_SMS_CODE = "SMS_465896079";
        }
    }

    //优惠申请通知
    private final static String TEMPLATE_SMS_DISCOUNT = "SMS_252710269";
    @Resource
    SmsRecordService smsRecordService;


//    @Test
//    public void test() throws Exception {
//        sendDiscountNotice("13533031787","1234567890",  new BigDecimal(10),new BigDecimal(1),"ljh","ljh2");
//    }


    /**
     * 发送优惠申请通知
     *
     * @param mobile      手机号
     * @param orderNo     订单号
     * @param totalAmount 当前金额
     * @param discunt     优惠金额
     * @param name        申请人
     * @param user        收货人
     */
    public void sendDiscountNotice(String mobile, String orderNo, BigDecimal totalAmount, BigDecimal discunt, String name, String user) {
        try {
            String orderNo2 = orderNo.substring(orderNo.length() - 6, orderNo.length());
            Map<String, Object> map = new HashMap<>();
            map.put("orderno", orderNo2);
            map.put("totalmount", totalAmount);
            map.put("discunt", discunt);
            map.put("name", name);
            map.put("user", user);
            this.send(mobile, this.TEMPLATE_SMS_DISCOUNT, map);
        } catch (Exception e) {
            log.error("发送优惠申请通知失败", e);
        }
    }


    /**
     * 发送短信验证码
     *
     * @param mobile    手机号
     * @param key       拖拽式验证码的key
     * @param vrifyCode 拖拽式验证码的x轴值
     * @throws Exception
     */
    public void sendSms(String mobile, String key, String vrifyCode) throws Exception {

        if (mobile.equals("13000000000")) {
            return;
        }
        if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(vrifyCode)) {
            boolean b = this.checkVrifyCode(key, vrifyCode);
            if (!b) {
                throw new RemoteServiceException("验证码不通过");
            }
        }
        //限制不能频繁发送
        //this.checkSendTime(mobile);

        //6位随机数
        Random random = new Random();
        int num = (int) (random.nextDouble() * (1000000 - 100000) + 100000);
        String code = String.format("%06d", num);
        HashMap<String, Object> map = new HashMap<>();
        map.put("code", code);
        String content = this.send(mobile, TEMPLATE_SMS_CODE, map);

        //记录短信内容
        SmsRecord smsRecord = new SmsRecord();
        smsRecord.setPhone(mobile);
        smsRecord.setContent(content);
        smsRecord.setCreateTime(new Date());
        smsRecord.insert();

        //记录发送的code
        redisUtil.set(Constant.RedisPrefix.SMS + ":" + mobile, code, 5 * 60);
    }


    /**
     * 校验短信验证码的正确性
     */
    public void checkSmsCode(String mobile, String code) throws RemoteServiceException {
        String redisKey = Constant.RedisPrefix.SMS + ":" + mobile;
        String value = (String) redisUtil.get(redisKey);
        if (!StringUtils.equals(value, code)) {
            throw new RemoteServiceException("短信验证失败");
        }
        redisUtil.del(redisKey);
    }


    /**
     * 验证手机号码两次发送的间隔，不能太短
     *
     * @param mobile 手机号码
     * @throws RemoteServiceException
     */
    private void checkSendTime(String mobile) throws RemoteServiceException {
        String key = Constant.RedisPrefix.SMS + ":" + mobile;
        if (redisUtil.hasKey(key)) {
            throw new RemoteServiceException("发送短信间隔时间太短,请耐心等候");
        }
    }


    /**
     * 校验验证码
     *
     * @param key
     * @param vrifyCode
     * @return
     */
    private boolean checkVrifyCode(String key, String vrifyCode) throws RemoteServiceException {
        Object serverCode = redisUtil.get(Constant.RedisPrefix.VERIFICATION + ":" + key);
        if (serverCode == null) {
            throw new RemoteServiceException("验证码超时");
        }
        //允许拖拽式验证码误差+-10
        int code = (int) serverCode;
        int code2 = Integer.parseInt(vrifyCode);
        if (code >= (code2 - 15) && code <= (code2 + 15)) {
            redisUtil.del(Constant.RedisPrefix.VERIFICATION + ":" + key);
            return true;
        } else {
            throw new RemoteServiceException("验证码校验不通过");
        }
    }


    private String send(String mobile, String templateCode, Map<String, Object> param) throws ClientException, com.aliyuncs.exceptions.ClientException {

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", mobile);
        request.putQueryParameter("SignName", SIGN_NAME);  //需要在平台上添加
        request.putQueryParameter("TemplateCode", templateCode);  //模版id 需要在拼台上添加

        String content = JSON.toJSONString(param);
        log.info("短信发送的内容" + content + mobile);
        request.putQueryParameter("TemplateParam", content);
        CommonResponse response = client.getCommonResponse(request);
        //打印返回数据
        log.info("短信验证返回数据 ：" + response.getData());

        String dateRes = response.getData();
        Map<String, Object> smsRsp = JSON.parseObject(dateRes);
        //获取数据
        String codeRes = smsRsp.get("Code").toString();
        if (!codeRes.equals("OK")) {
            log.error("短信发送失败,mobile:{}", mobile);
        }
        return content;
    }


    public void sendSms2(String mobile, String key, String vrifyCode) throws Exception {
        if (StringUtils.isNotBlank(key) && StringUtils.isNotBlank(vrifyCode)) {
            boolean b = this.checkVrifyCode(key, vrifyCode);
            if (!b) {
                throw new RemoteServiceException("验证码不通过");
            }
        }
        //限制不能频繁发送
        this.checkSendTime(mobile);

        //6位随机数
        if (!active.equals("prd")) {
            //记录发送的code
            redisUtil.set(Constant.RedisPrefix.SMS + ":" + mobile, "000000", 1 * 60);
        } else {
            Random random = new Random();
            int num = (int) (random.nextDouble() * (1000000 - 100000) + 100000);
            String code = String.format("%06d", num);
            HashMap<String, Object> map = new HashMap<>();
            map.put("code", code);
            String content = this.send(mobile, TEMPLATE_SMS_CODE, map);

            String beforeDate = DateUtils.formatDate1(new Date());
            long count = smsRecordService.count(new LambdaQueryWrapper<SmsRecord>()
                    .eq(SmsRecord::getPhone, mobile)
                    .ge(SmsRecord::getCreateTime, beforeDate + " 00:00:00")
                    .le(SmsRecord::getCreateTime, beforeDate + " 23:59:59"));
            // 一天内超过5次登录，不再发短信
            if (count > 5) {
                throw new RemoteServiceException("今天发送短信次数超过5次，今天禁止登录！");
            }

            //记录短信内容
            SmsRecord smsRecord = new SmsRecord();
            smsRecord.setPhone(mobile);
            smsRecord.setContent(content);
            smsRecord.setCreateTime(new Date());
            smsRecord.insert();

            //记录发送的code
            redisUtil.set(Constant.RedisPrefix.SMS + ":" + mobile, code, 2 * 60);
        }
    }
}
