package com.bohuikeji.frame.module.admin.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bohuikeji.frame.module.admin.component.RedisUtil;
import jodd.http.HttpRequest;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 51易迅短信平台工具类
 * 内蒙古锦贤三网行业
 * APPID：LHW-SMS-03ZEV
 * 秘钥：8E9FC62D170554C3
 * http://www.51yixun.com/doc/msg.html 接口文档
 *
 * 内蒙古锦贤三网物流
 * APPID：LHW-SMS-0T6PH，秘钥：AD7FFB4C865654C4
 * http://www.51yixun.com/doc/msg.html 接口文档
 * @author sjh
 */
@Slf4j
public class YiXunGmsUtils {



    public static String SEND_URL="http://sms.51yixun.com:8200/sms/send";

    public static String REPORT_URL="http://sms.51yixun.com:8200/sms/report";

    public static String PRICE_URL="http://sms.51yixun.com:8200/sms/balance";

    public static String MO_URL="http://sms.51yixun.com:8200/sms/mo";

    /**
     * 短信验证码
     */
    public static String APPID="LHW-SMS-03ZEV";
    public static String secretKey="8E9FC62D170554C3";

    /**
     * 普通物流短信
     */
    public static String APPID_2="LHW-SMS-0T6PH";
    public static String secretKey_2="AD7FFB4C865654C4";

    public static String MSG_SIGN="【同城急送】";

    public static DateTimeFormatter dataTimeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    /**
     * 获取缓存的KEY
     * @param phone 发送手机号码
     * @param templateCode 发送模板号
     * @return
     */
    public static String getCacheKey(String phone,String templateCode){
        return "gms:cache:"+phone+":"+templateCode;
    }




    /**
     * 短信预警条数
     */
    public static int MSG_WARN=500;

    /**
     * 预警人手机号
     */
    public static String[] MSG_NOTICE={"15771335697","18347923617"};
    private static final Map<String,String> tmpl=new HashMap<>(22);
    private static final RedisUtil redisUtil=SpringUtil.getBean(RedisUtil.class);
    static {
        //任意内容
        tmpl.put("SMS_ALL_TXT","${txt}");
        tmpl.put("SMS_184115918","您的验证码为:${code},有效期为10分钟");
        tmpl.put("SMS_220601364","同城急送用户：您提交的营销骑手申请已收到，请点击链接下载骑手App进行信息认证即可使用，链接：https://os.tcjskd.com/delivery/app/new/download/page/1");
        tmpl.put("SMS_210705215","尊敬的客户您好，您的订单：${order},在规定时间内未完成支付系统已为您自动取消，如需配送请再次下单。");
        tmpl.put("SMS_196145194","${server}异常，位于节点：${node}，错误频次：${times}，日志详情已发至邮箱：${emails}");
        tmpl.put("SMS_192835836","尊敬的客户您好，您的订单：${order}已配送完成，投诉有效时间为24小时！同城急送期待为您再次服务。");
        tmpl.put("SMS_192835835","尊敬的客户您好，您的订单：${order}，派送员正在配送，请您留意接听电话。");
        tmpl.put("SMS_190265757","尊敬的客户您好，由于${region}的该区域运力不足，暂时无法为您提供配送服务，系统将为您取消订单，给您带来的不便敬请谅解！");
        tmpl.put("SMS_185720232","尊敬的客户您好，您的订单：${order}，已退款成功，退款金额：${price}");
        tmpl.put("SMS_185560840","尊敬的客户您好，您的订单：${order}，已确认收货。感谢您的信赖，祝您生活愉快！");
        tmpl.put("SMS_185560837","尊敬的客户您好，您的订单：${order}，现派送员已接单，请您留意接听电话，派送员稍后将与您联系。");
        tmpl.put("SMS_184120850","您好,${name}. 您提交的审核资料,已${context}");
        tmpl.put("SMS_184105904","尊敬的用户,您好.您的订单号:${order},现在订单状态为:${content}");
        tmpl.put("SMS_WARN","系统消息：短信余量不足预警提示——当前账户短信剩余：${surplus}条，已经达到预警值："+MSG_WARN);
        tmpl.put("SMS_ORDER_THIRD_30","您的订单：${order}，配送员：${courier} 已接单，正在火速赶往取件处，请您留意接听电话.....");
        tmpl.put("SMS_ORDER_THIRD_30_pay","您的订单：${order}，配送员：${courier} 已接单，正在火速赶往取件处，请您尽快完成支付，超时系统将为您取消订单......");
        tmpl.put("SMS_ORDER_THIRD_40","您的订单：${order}，您的订单已揽收完成快递中，${desc}，请您提前和收件人联系收取。");
        tmpl.put("SMS_ORDER_THIRD_40_pay","您的订单：${order}，开始进行配送，${desc}，请您尽快完成支付，避免订单滞留......");
        tmpl.put("SMS_ORDER_THIRD_50","您的订单：${order}，已送达，感谢您的信赖与支持！如有疑问您可以联系本单配送员：${courier}进行确认，或致电客服：400-690-0105。");
        tmpl.put("SMS_ORDER_THIRD_50_pay","您的订单：${order}，已送达，感谢您的信赖与支持！温馨提示：当前订单尚未支付，您可以通过”同城急送“小程序或APP进行支付。如有疑问您可联系本单配送员：${courier}，或致电客服：400-690-0105进行确认，期待您的再次使用，谢谢！");
        tmpl.put("SMS_ORDER_THIRD_50_pay_CONTINUE","温馨提示：您有一笔订单${order}尚未支付，请不要忘记哦~");
        tmpl.put("SMS_TEMP_ADDRESS_EDIT","用户：${user}，修改了订单：${order}。\r\n寄件地址：${mag}\r\n收件地址：${rep}");
        tmpl.put("SMS_ORDER_SUPPLY_H5","您的订单：${order}，快递员已取件完成，待支付差价：${price}元，请尽快完成支付(超时订单将被拦截退回)以免影响正常配送时效，也可以前往客户端进行查看支付，点击查看费用详情：${url}");
        tmpl.put("SMS_ORDER_PAY_TIMEOUT_JD","您的订单：${order}，等待支付即将超时，2小时后将发起运输拦截，配送物品将原路退回。");
    }

    /**
     * 发送任意短信
     * @param phone 电话
     * @param txt 文本
     * @return
     */
    public static boolean sendTxt(String phone,String txt){
        return sendMsg(phone,"SMS_ALL_TXT","txt",txt);
    }

    /**
     * 发送短信——固定订单参数
     * @return
     */
    public static  boolean sendMsg(String phone,String templateCode,String param,String value){
        Map<String,Object> params=new HashMap<>(1);
        params.put(param,value);
        return sendMsg(phone,templateCode,params);
    }

    /**
     * 发送短信
     * @param phone 手机号
     * @param templateCode 模板号
     * @param params 参数
     * @return
     */
    public static boolean sendMsg(String phone,String templateCode, Map<String,Object> params){
        return sendMsg(phone,templateCode,params,false);
    }

    /**
     * 发送短信
     * @param phone
     * @param templateCode
     * @param params
     * @param isCache 是否将短信放入缓存区，用于其他业务读取发送记录，缓存有效期为30分钟
     * @return
     */
    public static boolean sendMsg(String phone,String templateCode, Map<String,Object> params,boolean isCache){
        String content=MSG_SIGN+tmpl.get(templateCode);
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String k = entry.getKey();
            Object v = entry.getValue();
            content = content.replace("${" + k + "}", v.toString());
        }
        Map<String,String> reqParams=getPublicParams("SMS_184115918".equals(templateCode));
        reqParams.put(phone, content);
        String resStr=HttpRequest.get(SEND_URL).query(reqParams).send().bodyText();
        JSONObject res=JSON.parseObject(resStr);
        if("SUCCESS".equals(res.getString("code"))){
            if (isCache){
                //放入缓存
                redisUtil.set(getCacheKey(phone,templateCode),content, Duration.ofMinutes(30).getSeconds());
            }
            return true;
        }
        log.error("【短信发送失败】号码：{}，发送内容：{},返回信息：{}",phone,content,resStr);
        return false;
    }

    public static JSONObject getReport(){
        String resStr=HttpRequest.get(REPORT_URL).query(getPublicParams(false)).send().bodyText();
        log.info("状态查询接口接口返回：{}",resStr);
        return null;
    }
    public static JSONObject getPrice(){
        String resStr=HttpRequest.get(PRICE_URL).query(getPublicParams(false)).send().bodyText();
        log.info("余额接口接口返回：{}",resStr);
        return null;
    }
    public static JSONObject geMo(){
        String resStr=HttpRequest.get(MO_URL).query(getPublicParams(false)).send().bodyText();
        log.info("查询上行信息接口接口返回：{}",resStr);
        return null;
    }

    @Test
    public void test(){
       Map<String,Object> params=new HashMap<>(1);
        params.put("user","孙晋惠");
        params.put("order","A12345698745213548");
        params.put("mag","内蒙古自治区呼和浩特市玉泉区昭乌达路三里应B区东门。");
        params.put("rep","内蒙古自治区呼和浩特市玉泉区昭乌达路三里应B区东门。");

        sendMsg("15771335697","SMS_TEMP_ADDRESS_EDIT",params);
        //getReport();
    }

    /**
     * 获取时间戳字符串
     * @return
     */
    private static String getTimestamp(){
        return LocalDateTime.now().format(dataTimeFormat);
    }

    /**
     * 获取签名
     * @param timestamp
     * @return
     */
    private static String sign(String timestamp,String appId,String secretKey){
        return DigestUtils.md5DigestAsHex((appId+secretKey+timestamp).getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 获取默认参数
     * @param isCode 是否为验证码短信
     * @return
     */
    public static Map<String,String> getPublicParams(boolean isCode){
        Map<String,String> reqParams=new HashMap<>();
        String timestamp=getTimestamp();
        reqParams.put("appId",isCode?APPID:APPID_2);
        reqParams.put("timestamp",timestamp);
        reqParams.put("sign",sign(timestamp,isCode?APPID:APPID_2,isCode?secretKey:secretKey_2));
        reqParams.put("batchId","10");
        return reqParams;
    }

}
