package com.hai.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.security.VerifyCode;
import com.hai.common.security.VerifyCodeStorage;
import com.hai.common.utils.RedisUtil;
import com.hai.model.MtSmsMessageModel;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.net.ssl.*;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * @author Sum1Dream
 * @version 1.0.0
 * @serviceName MessageConfig.java
 * @Description // 短信接口
 * @createTime 15:28 2022/5/6
 **/
@Component
public class MessageConfig {

    // 华为短信模版ID
    // 嗨森逛绑定工会卡
    public final static String HWMSG_ID1 = "SMS_22041400010";
    // 嗨森逛积分支付密码重置
    public final static String HWMSG_ID2 = "SMS_22041400009";
    // 嗨森逛注册
    public final static String HWMSG_ID3 = "SMS_22041400008";
    // 嗨森逛公司账户充值验证码
    public final static String HWMSG_ID4 = "SMS_22041400005";
    // 嗨森逛账号登录
    public final static String HWMSG_ID5 = "SMS_22050700002";

    // 嗨森逛账号登录支付密码修改
    public final static String HWMSG_ID6 = "SMS_22072500001";

    private static final String[] HEX_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};

    private static Logger log = LoggerFactory.getLogger(MessageConfig.class);

    /**
     * 设置不验证主机
     */
    private static final HostnameVerifier DO_NOT_VERIFY = (hostname, session) -> true;

    @Resource
    private RedisUtil redisUtil;

    /**
    * @Author Sum1Dream
    * @name sendSmsCodeHw.java
    * @Description // 普通华为短信验证码发送
    * @Date 16:31 2022/5/6
    * @Param [java.lang.String, java.lang.String]
    * @return java.lang.String
    */
    public String sendSmsCodeHw(String phone, String HWMSG) throws Exception {
        VerifyCode verifyCode = VerifyCodeStorage.getDate(phone);
        String smsCode;
        if (verifyCode != null) {
            smsCode = verifyCode.getObject();
        } else {
            // 生成随机6位验证码
            smsCode = String.valueOf(new Random().nextInt(899999) + 100000);
        }
        // ip：port根据实际情况填写
        String url = "https://139.9.32.119:18312/common/sms/sendTemplateMessage";
        Map<String, String> templateParas = new HashMap<>();
        templateParas.put("code", smsCode);
        String account = "760887"; //实际账号
        String password = "Z.o'&mO%7_?5M,Br"; //实际密码

        // 如果请求正文不包含签名名称，则设置签名为空
        Map<String, Object> body = buildRequestBody(phone, HWMSG, templateParas, account, password);
        if (null == body || body.isEmpty()) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "参数校验失败");
        }

        HttpsURLConnection connection;
        InputStream is = null;
        BufferedReader br = null;
        trustAllHttpsCertificates();

        URL realUrl = new URL(url);
        connection = (HttpsURLConnection) realUrl.openConnection();
        connection.setHostnameVerifier(DO_NOT_VERIFY);
        connection.setDoInput(true); // 设置可输入
        connection.setDoOutput(true); // 设置该连接是可以输出的
        connection.setRequestMethod("POST"); // 设置请求方式
        connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
        ObjectMapper objectMapper = new ObjectMapper();
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
        pw.write(objectMapper.writeValueAsString(body));
        pw.flush();
        pw.close();

        int status = connection.getResponseCode();
        if (200 == status) { // 200
            is = connection.getInputStream();
        } else { // 400/401
            is = connection.getErrorStream();
        }
        br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String line = null;
        StringBuilder result = new StringBuilder();
        while ((line = br.readLine()) != null) { // 读取数据
            result.append(line + "");
        }
        connection.disconnect();
        System.out.println(result.toString());

        is.close();
        br.close();

        redisUtil.set("SMS_" + phone, smsCode, 60 * 10);

        return "发送成功";
    }


    // msisdn, smsTemplateId, paramValues, countryID
    public static Map<String, Object> buildRequestBody(String msisdn, String smsTemplateId,
                                                       Map<String, String> paramValues, String accout, String passward) {
        if (null == msisdn || null == smsTemplateId || null == accout || null == passward) {
            System.out.println(
                    "buildRequestBody(): mobiles, templateId or templateParas or account or password is null.");
            return null;
        }

        Map<String, Object> map = new HashMap<String, Object>();
        List<MtSmsMessageModel> requestLists = new ArrayList<MtSmsMessageModel>();
        MtSmsMessageModel mtSmsMessage = new MtSmsMessageModel();
        List<String> mobiles = new ArrayList<String>();
        mobiles.add(msisdn);
        mtSmsMessage.setMobiles(mobiles);
        mtSmsMessage.setTemplateId(smsTemplateId);
        mtSmsMessage.setTemplateParas(paramValues);
        mtSmsMessage.setSignature("【嗨森逛】");
        requestLists.add(mtSmsMessage);
        map.put("account", accout);
        map.put("password", passward);
        map.put("requestLists", requestLists);
        return map;
    }

    static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return;
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                        return;
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                }
        };
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

}
