package com.liquidnet.service.kylin.utils;

import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.UserPathDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 顺丰     ShunfengSignUtils　ß
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-06-24 8:00 下午
 */
@Component
@Slf4j
public class ShunfengSignUtils {
    /**
     * appId
     */
    @Value("${liquidnet.express.shunfeng.appid}")
    private String APP_ID;
    /**
     * sk
     */
    @Value("${liquidnet.express.shunfeng.sk}")
    private String SK;
    /**
     * url
     */
    @Value("${liquidnet.express.shunfeng.url}")
    private String URL;
    /**
     * 签名有效期（可根据实际业务设定）单位：毫秒
     */
    private final static Long CHECK_TIME = 600000L;

    /**
     * 生成签名并请求
     * @param hbody 请求body
     * @return
     */
    public String generateSignatureAndRequestNew(Map<String, String> hbody, String url) {
        long currentTimeMillis = System.currentTimeMillis(); // 时间戳
        String timestamp = currentTimeMillis + "";
        hbody.put("companyId", APP_ID);
        String body = JsonUtils.toJson(hbody);
        // 生成签名
        String sign = genSign(timestamp,body);

        Map<String, String> headers = new HashMap<>();
        headers.put("sendAppId", APP_ID);
        headers.put("timestamp", timestamp);
        headers.put("sign", sign);
        headers.put("Content-Type", "application/json;charset=utf-8");
        headers.put("Accept", "application/json");
        Map<String, String> querys = new HashMap<>();
        try {
            HttpEntity httpEntity = new StringEntity(body, "utf-8");
            String post = HttpsUtils.post(URL + url, headers, querys, httpEntity);
            return post;
        } catch (Exception e) {
            System.out.println("发送请求失败");
            e.printStackTrace();
            return e.getMessage();
        }
    }

    /**
     * 生成签名并请求 线上Received fatal alert:handshake_failure 废弃
     * @param hbody 请求body
     * @return
     */
    public String generateSignatureAndRequest(HashMap<String, Object> hbody, String url) {
        long currentTimeMillis = System.currentTimeMillis(); // 时间戳
        String timestamp = currentTimeMillis + "";
        hbody.put("companyId", APP_ID);
        String body = JsonUtils.toJson(hbody);
        // 生成签名
        String sign = genSign(timestamp,body);

        CloseableHttpClient client = HttpClients.createSystem();
        /*SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext,
                NoopHostnameVerifier.INSTANCE);*/
        // 请求下单地址
        HttpPost httpPost = new HttpPost(URL + url);
        // sendAppId（sendAppId需赋值appId）
        httpPost.addHeader("sendAppId", APP_ID);
        // 时间戳需和获取验签时一致！！！
        httpPost.addHeader("timestamp", timestamp);
        // 签名
        httpPost.addHeader("sign", sign);
        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
        httpPost.addHeader("Accept", "application/json");
        // 请求body体需和获取验签时一致且编码UTF8！！！
        httpPost.setEntity(new StringEntity(body, "utf-8"));
        CloseableHttpResponse response = null;
        log.info(UserPathDto.setData("header", "", httpPost.getAllHeaders()));
        log.info(UserPathDto.setData("body", "", body));

        try {
            response = client.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                System.out.println("发送请求成功");
                HttpEntity entity = response.getEntity();
                // 发送响应且编码UTF8！！！
                return EntityUtils.toString(entity, "utf-8");
            }
        } catch (Exception e) {
            System.out.println("发送请求失败");
            e.printStackTrace();
            return e.getMessage();
        } finally {
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 生成签名
     * @param timestamp 时间戳
     * @param body 请求body
     * @return
     */
    private String genSign(String timestamp, String body) {
        if (StringUtils.isEmpty(body)) {
            body = "";
        }

        StringBuffer sb = new StringBuffer();
        sb.append(body);
        sb.append("&sk=").append(SK);
        sb.append("&timestamp=").append(timestamp);

        byte[] bytes = DigestUtils.sha512(sb.toString());
        return Base64.encodeBase64URLSafeString(bytes);
    }

}