package com.xhpc.general.service;

import cn.hutool.json.JSONUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.xhpc.common.core.domain.R;
import com.xhpc.common.core.web.domain.AjaxResult;
import com.xhpc.common.redis.service.RedisService;
import com.xhpc.common.security.service.TokenService;
import com.xhpc.general.constant.AliyunSendResult;
import com.xhpc.general.constant.AliyunTemplate;
import com.xhpc.general.domain.XhpcSms;
import com.xhpc.general.mapper.XhpcSmsMapper;
import com.xhpc.general.util.sms.SmsUtil;
import com.xhpc.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author yuyang
 * @date 2021/7/30 18:50
 */
@Slf4j
@Service
public class XhpcSmsServiceImpl implements IXhpcSmsService {

   public static RedisService REDIS;
   public static final String accessKeyId = "LTAI5tHxc8hrG6cT5nDtEkiV";
   public static final String accessKeySecret = "5kFEaIFE7eeODxKQwD5mvTRF48MK6w";

   private static final Logger logger = LoggerFactory.getLogger(XhpcSmsServiceImpl.class);
   @Autowired
   private RedisService redisService;
   @Autowired
   private XhpcSmsMapper xhpcSmsMapper;
   @Autowired
   private TokenService tokenService;

   @PostConstruct
   public void init() {

      REDIS = redisService;
   }


   @Override
   public AjaxResult getLogonPhoneCode(String phone, String signatureName, String templateId,String account) {

      String random = getRandom();
      HashMap<String, String> paramMap = new HashMap<>();
      paramMap.put("code", random);
      String content = null;
      return send(phone, content, random, signatureName, templateId, paramMap,account);
   }

   @Override
   public List<Map<String, Object>> getList(Integer status, String phone) {
      LoginUser loginUser = tokenService.getLoginUser();
      return xhpcSmsMapper.getList(status,phone,loginUser.getTenantId());
   }

   @Override
   public AjaxResult send(String phone, String content, String random, String signatureName, String templateId, Map<String, String> paramMap,String account) {
      //调用接口
      String pattern = "^([1][0-9]{10})";
      Pattern compile = Pattern.compile(pattern);
      Matcher m = compile.matcher(phone);
      boolean isMatch = m.matches();
      if (!isMatch) {
         return AjaxResult.error("1003", "请输入正确的手机号");
      }
      //添加短信记录
      XhpcSms xhpcSms =new XhpcSms();
      try {
         String pvToken ="";
         String token ="";
         if(account !=null){
            //用户使用的Key
            pvToken = "pvToken:" + account;
            //用户频繁调用的判断的Key
            token = "token:" + account;
            String cacheObject = REDIS.getCacheObject(token);
            if (cacheObject != null) {
               return AjaxResult.error("1012", "操作过于频繁，请于1分钟后重试");
            }
         }else{
            //用户使用的Key
             pvToken = "pvToken:" + phone;
            //用户频繁调用的判断的Key
             token = "token:" + phone;
            String cacheObject = REDIS.getCacheObject(token);
            if (cacheObject != null) {
               return AjaxResult.error("1012", "操作过于频繁，请于1分钟后重试");
            }
         }
         //使用阿里云发送通知短信
         Map<String, String> neededParam = null;
         try {
            neededParam = aliyunSmsNotice(phone, signatureName, templateId, paramMap);
         } catch (Exception e) {
            throw new RuntimeException("阿里短信服务异常,neededParam为null");
         }

         if (!"".equals(random) && random != null) {
            xhpcSms.setCode(random);
         }
         xhpcSms.setPhone(phone);
         xhpcSms.setContent(neededParam.get("templateContent"));
         xhpcSms.setCreateTime(new Date());
         xhpcSms.setRemark(neededParam.get("jsonResult"));

         //判断发送结果
         String statusCode = neededParam.get("statusCode");
         if (statusCode.equals(AliyunSendResult.SUCCESS)) {
            REDIS.setCacheObject(pvToken, random, 300L, TimeUnit.SECONDS);
            //1分钟有效时间设置，防止用户频繁调用
            REDIS.setCacheObject(token, random, 60L, TimeUnit.SECONDS);
            xhpcSms.setStatus(0);
            xhpcSmsMapper.addXhpcSms(xhpcSms);
            return AjaxResult.success();
         } else {
            xhpcSms.setStatus(1);
            xhpcSmsMapper.addXhpcSms(xhpcSms);
            return AjaxResult.error(1012, "服务器繁忙，请稍后再试");
         }
      } catch (Exception e) {
         e.printStackTrace();
        // xhpcSms.setStatus(3);
        // xhpcSmsMapper.addXhpcSms(xhpcSms);
         return AjaxResult.error(1010,"服务器繁忙，请稍后再试");
      }
   }

   private String getRandom(){
      Random rnd = new Random();
      int i = rnd.nextInt(999999);
      if(i<100000){
         i=i+100000;
      }
      return i+"";
   }

   @Override
   public void sendNotice(String phone, String signatureName, String templateId, Map<String, String> paramMap) {

      XhpcSms xhpcSms = new XhpcSms();
      try {
         System.out.println("============发送短信==================");
         System.out.println("============phone=================="+phone);
         System.out.println("============signatureName=================="+signatureName);
         System.out.println("============templateId=================="+templateId);
         System.out.println("============paramMap=================="+paramMap.toString());

            String captcha = redisService.getCacheObject(phone+":"+templateId);
            if (!templateId.equals(captcha)) {

               //使用阿里云发送通知短信
               Map<String, String> neededParam = aliyunSmsNotice(phone, signatureName, templateId, paramMap);
               System.out.println("============neededParam=================="+neededParam);
               //获取模板内容
               String templateContent = neededParam.get("templateContent");
               System.out.println("============templateContent=================="+templateContent);
               //封装信息
               xhpcSms.setPhone(phone);
               xhpcSms.setContent(templateContent);
               xhpcSms.setCreateTime(new Date());
               xhpcSms.setRemark(neededParam.get("jsonResult"));

               //判断发送结果
               String statusCode = neededParam.get("statusCode");
               if (AliyunSendResult.SUCCESS.equals(statusCode)) {
                  xhpcSms.setStatus(0);
               } else {
                  xhpcSms.setStatus(1);
               }
               xhpcSmsMapper.addXhpcSms(xhpcSms);
               redisService.setCacheObject(phone+":"+templateId, templateId, 120L, TimeUnit.SECONDS);
            }else{
               System.out.println("============不发生发送短信==================");
            }


      } catch (Exception e) {
         e.printStackTrace();
         xhpcSms.setStatus(3);
         xhpcSmsMapper.addXhpcSms(xhpcSms);
      }

   }

   @Override
   public Object getAliyunShortMessageInfo() {
      LoginUser loginUser = tokenService.getLoginUser();
      Long successMessage = xhpcSmsMapper.querySumOfSuccessMessage(loginUser.getTenantId());
      Long failMessage = xhpcSmsMapper.querySumOfFailMessage(loginUser.getTenantId());
      Long sumOfMessage = successMessage + failMessage;
      Map<String, Long> messageInfoMap = new HashMap<>();
      messageInfoMap.put("successMessage", successMessage);
      messageInfoMap.put("failMessage", failMessage);
      messageInfoMap.put("sumOfMessage", sumOfMessage);
      return messageInfoMap;
   }

   /**
    * 使用阿里云服务发送通知短信
    *
    * @param phone
    * @param signatureName
    * @param templateId
    * @param paramMap      模板参数集合
    * @return
    * @throws Exception
    */
   public Map<String, String> aliyunSmsNotice(String phone, String signatureName, String templateId, Map<String, String> paramMap) throws Exception {

      //调用阿里云API发送请求
      Client client = SmsUtil.createClient(accessKeyId, accessKeySecret);
      SendSmsRequest sendSmsRequest = new SendSmsRequest();
      sendSmsRequest.setPhoneNumbers(phone);
      sendSmsRequest.setSignName(signatureName);
      sendSmsRequest.setTemplateCode(templateId);
      //添加模板参数
      String templateParam = JSONUtil.toJsonStr(paramMap);
      sendSmsRequest.setTemplateParam(templateParam);
      SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
      //获取发送结果状态码
      String statusCode = sendSmsResponse.getBody().getCode();
      //获取实际的模板内容
      String templateContent = getTemplateContent(templateId, paramMap);
      //获取阿里云的返回值json字符串
      SendSmsResponseBody body = sendSmsResponse.getBody();
      String jsonResult = JSONUtil.toJsonStr(body);
      //存放后面需要使用的返回值
      HashMap<String, String> valueParam = new HashMap<>();
      valueParam.put("statusCode", statusCode);
      valueParam.put("templateContent", templateContent);
      valueParam.put("jsonResult", jsonResult);
      return valueParam;
   }

   private String getTemplateContent(String templateId, Map<String, String> paramMap) throws Exception {

//      if (AliyunTemplate.CHARGE_FULL.equals(templateId)) {
//         String battery = paramMap.get("battery");
//         return "尊敬的用户，你的车辆已充电达至设定的SOC:" + battery + "%并停止充电，请您尽快将车辆挪走以方便他人使用充电桩，谢谢合作。";
//      }
      if (AliyunTemplate.CHARGE_MONEY_INSUFFICIENT.equals(templateId)) {
         String money = paramMap.get("money");
         return "尊敬的用户，你的账户余额小于" + money + "元,为不影响您的正常充电，请您尽快充值交费，谢谢。";
      }
      if (AliyunTemplate.DIRECT_STREAM_PILE_STOP_CHARGE.equals(templateId)) {
         String elec = paramMap.get("elec");
         String sumMoney = paramMap.get("sumMoney");
         return "尊敬的用户，你的爱车已停止充电，请尽快挪车。电量为：" + elec + "，总费用为：" + sumMoney + "元，充电费用明细，请查询翔桦充电小程序，谢谢。";
      }
      if (AliyunTemplate.INTERFLOW_STREAM_PILE_STOP_CHARGE.equals(templateId)) {
         String sumMoney = paramMap.get("sumMoney");
         return "尊敬的用户，你的爱车已停止充电，请尽快挪车。总费用为：" + sumMoney + "元，充电费用明细，请查询翔桦充电小程序，谢谢。";
      }
      if (AliyunTemplate.VALIDATE_CODE.equals(templateId)) {
         String code = paramMap.get("code");
         return "您的验证码是：" + code + "，有效期为5分钟。如非本人操作，可不用理会。";
      }
      if (AliyunTemplate.OPERATOR_PLACEHOLDER_ORDER_MONEY.equals(templateId)) {
         String time = paramMap.get("time");
         String sumMoney = paramMap.get("sumMoney");
         String number = paramMap.get("number");
         return "尊敬的用户，你的爱车已停止充电"+time+"分钟，前30分钟免费，平台收取本次设备占用费："+sumMoney+"元，占位费费用将从余额扣除，占位费明细请查询翔桦充电小程序我的历史订单，试运行期间前三次免费，当前免费次数为"+number+"，充电结束请及时挪车。";
      }
      if (AliyunTemplate.OPERATOR_PLACEHOLDER_ORDER.equals(templateId)) {
         String time = paramMap.get("time");
         String sumMoney = paramMap.get("sumMoney");
         String number = paramMap.get("number");
         return "尊敬的用户，你的爱车已停止充电"+time+"分钟，前30分钟免费，平台收取本次设备占用费："+sumMoney+"元，占位费费用将从余额扣除，占位费明细请查询翔桦充电小程序我的历史订单，试运行期间前三次免费，当前免费次数为"+number+"，充电结束请及时挪车。";
      }

//      if (AliyunTemplate.REFUND_FAIL.equals(templateId)) {
//         return "退款-尊敬的用户，当前退款人数较多，申请退款失败，请您重新提交申请！";
//      }
//      if (AliyunTemplate.OPERATOR_ORDER_REFUND.equals(templateId)) {
//         String number=paramMap.get("number");
//         return "【小华充电订单异常】尊敬的管理员，用户退款订单："+number+"，有问题请速速查看。";
//      }
      throw new Exception("没有对应的模板id");
   }

   public static void main(String[] args) {
      Client client = null;
      try {
         client = SmsUtil.createClient(accessKeyId, accessKeySecret);

      SendSmsRequest sendSmsRequest = new SendSmsRequest();
      sendSmsRequest.setPhoneNumbers("18123374652");
      sendSmsRequest.setSignName("翔桦充电订单异常");
      sendSmsRequest.setTemplateCode("SMS_462691150");
      //添加模板参数
      HashMap<String, String> paramMap = new HashMap<>();
      paramMap.put("phone", "18123374652");
      paramMap.put("number", "45634654");
      paramMap.put("content", "【翔桦充电订单异常】尊敬的管理员，用户退款订单：741258963，有问题请速速查看。");
      String templateParam = JSONUtil.toJsonStr(paramMap);
      sendSmsRequest.setTemplateParam(templateParam);
      SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
      //获取发送结果状态码
      String statusCode = sendSmsResponse.getBody().getCode();
      //获取阿里云的返回值json字符串
      SendSmsResponseBody body = sendSmsResponse.getBody();
      String jsonResult = JSONUtil.toJsonStr(body);
      //存放后面需要使用的返回值
      HashMap<String, String> valueParam = new HashMap<>();
      valueParam.put("statusCode", statusCode);
      valueParam.put("templateContent", "【翔桦充电订单异常】尊敬的管理员，用户退款订单：324324324，有问题请速速查看。");
      valueParam.put("jsonResult", jsonResult);

         System.out.println("====valueParam======"+valueParam.toString());
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
