package com.cweb.controller;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hai.common.Base64Util;
import com.hai.common.security.VerifyCode;
import com.hai.common.security.VerifyCodeStorage;
import com.hai.common.utils.DateUtil;
import com.hai.common.utils.HttpsUtils;
import com.hai.common.utils.RedisUtil;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.model.MtSmsMessageModel;
import com.hai.model.ResponseData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
@Api(value = "内容管理 内容发布")
@RequestMapping(value = "/sms")
public class SmsContentController {

    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(CmsContentController.class);

    /**
     * 设置不验证主机
     */
    private static final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };


    @Resource
    private RedisUtil redisUtil;

//    @RequestMapping(value = "/sendSmsCode", method = RequestMethod.GET)
//    @ApiOperation(value = "发送短信验证码")
//    @ResponseBody
//    public ResponseData sendSmsCode(@RequestParam(value = "phone", required = true) String phone) {
//        try {
//            VerifyCode verifyCode = VerifyCodeStorage.getDate(phone);
//            String smsCode;
//            if (verifyCode != null){
//                smsCode = verifyCode.getObject();
//            }else{
//                // 生成随机6位验证码
//                smsCode = String.valueOf(new Random().nextInt(899999) + 100000);
//            }
//            String param = "88200409698&to="+phone+"&templateId=f42261f78d54488391f1d1ac4bd5bd3f&templateParas=[\"" + smsCode +"\"]";
//            Map<String,Object> body = new LinkedHashMap<>();
//            body.put("from", param);
//            String nonce = UUID.randomUUID().toString();
//            String created = DateUtil.date2String(new Date(), "yyyy-MM-dd'T'HH:mm:ss'Z'");
//            String passwordDigest = Base64Util.encode(encodeBySHA256(nonce + created + "9CWFv4NlaRX49n43VPA6eucZ8xeQ")) + "==";
//            Map<String,Object> header = new LinkedHashMap<>();
//            header.put("Authorization", "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"");
//            header.put("X-WSSE", "UsernameToken Username=\"QR5eMVrcW0Md6r634M6tf2i34cvb\",PasswordDigest=\""+passwordDigest+"\",Nonce=\""+nonce+"\",Created=\""+created+"\"");
//            JSONObject object = HttpsUtils.doSmsPost("https://rtcsms.cn-north-1.myhuaweicloud.com:10743/sms/batchSendSms/v1", body,header);
//            String code = object.getString("code");
//            if (code.equals("000000")) {
//                redisUtil.set(phone,smsCode, 60*10);
//                return ResponseMsgUtil.success("发送成功");
//            }
//            return ResponseMsgUtil.success(object);
//        } catch (Exception e) {
//            log.error("CmsContentController --> sendSmsCode() error!", e);
//            return ResponseMsgUtil.exception(e);
//        }
//    }

    @RequestMapping(value = "/sendSmsCode", method = RequestMethod.GET)
    @ApiOperation(value = "发送短信验证码")
    @ResponseBody
    public ResponseData sendSmsCodeHw(@RequestParam(value = "phone", required = true) String phone) {
        try {
            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";
            String msisdn = phone;
            String smsTemplateId = "SMS_21092300061";
            Map<String, String> templateParas = new HashMap<String, String>();
            templateParas.put("code", smsCode);
            String account = "760887"; //实际账号
            String password = "Z.o'&mO%7_?5M,Br"; //实际密码

            // If the request body does not contain the signature name, set signature to null.
            Map<String, Object> body = buildRequestBody(msisdn, smsTemplateId, templateParas, account, password);
            if (null == body || body.isEmpty()) {
                System.out.println("body is null.");
                return ResponseMsgUtil.success("");
            }


            HttpsURLConnection connection = null;
            InputStream is = null;
            BufferedReader br = null;
            trustAllHttpsCertificates();
            try {
                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");
                // connection.connect();
                ObjectMapper objectMapper = new ObjectMapper();
                PrintWriter pw = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8"));
                pw.write(objectMapper.writeValueAsString(body));
                pw.flush();
                pw.close();


                br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
                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());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {


                    if (null != is) {
                        is.close();
                    }
                    if (null != br) {
                        br.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            redisUtil.set("SMS_"+phone,smsCode, 60*10);
            return ResponseMsgUtil.success("发送成功");

        } catch (Exception e) {
            log.error("CmsContentController --> sendSmsCode() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }


    // 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());
    }

    @RequestMapping(value = "/getSmsCode", method = RequestMethod.GET)
    @ApiOperation(value = "发送短信验证码")
    @ResponseBody
    public ResponseData getSmsCode(@RequestParam(value = "phone", required = true) String phone) {
        try {
            return ResponseMsgUtil.success(redisUtil.get(phone));
        } catch (Exception e) {
            log.error("CmsContentController --> getSmsCode() error!", e);
            return ResponseMsgUtil.exception(e);
        }
    }


    public String encodeBySHA256(String str) {
        try{
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
            return getFormattedText(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return "";
    }

    private String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j=0;j<len;j++){
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }
}
