package com.cftech.waybill.utils;

import com.alibaba.fastjson.JSONObject;
import com.cftech.core.util.SystemConfig;
import com.cftech.order.model.Order;
import com.cftech.order.model.OrderDetail;
import com.cftech.orderdetail.model.OrderDetails;
import com.cftech.waybill.model.Waybill;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by 16444 on 2020/10/21.
 */
@Slf4j
public class FqHttpUtils {


    private static final String CHARACTER_CODE_UTF8 = "UTF-8";

    private static final int TIME_OUT_SECOND = 60000;

    private static RequestConfig requestConfig = null;

    /**
     * 顺丰合作伙伴Id
     */
    //private static final String partnerId = SystemConfig.p.getProperty("sf.partnerID");
    private static final String partnerId = "XXYZ";

    private static Map<String, String> headers = new HashMap<>();

    static {
        requestConfig = RequestConfig.custom()
                .setSocketTimeout(TIME_OUT_SECOND)//连接时间
                .setConnectTimeout(TIME_OUT_SECOND)//超时时间
                .setConnectionRequestTimeout(TIME_OUT_SECOND)
                .build();

        //headers.put("Accept", "application/x-www-form-urlencoded;charset=UTF-8");
        headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
    }

    /**
     * 服务端发送http get请求
     * @param url
     * @return
     */
    public static CloseableHttpEntity sendHttpGet(String url) {
        String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);

            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpGet.setHeader(entry.getKey(), entry.getValue());
            }
            httpGet.setHeader("X-Caller-Timestamp", dateStr);
            //取出url后参数
            if (url.contains("?")) {
                url = url.split("\\?")[0];
            }


            httpResponse = httpClient.execute(httpGet);
            InputStream inputStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuilder strber = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                strber.append(line);
            }
            reader.close();
            inputStream.close();
            log.info(strber.toString());
            return new CloseableHttpEntity(httpResponse.getStatusLine().getStatusCode(), strber == null? null:JSONObject.parseObject(strber.toString()));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static CloseableHttpEntity sendHttpPost(String url, JSONObject jsonObj) {
        String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //构建HttpClient实例
        CloseableHttpClient httpclient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            httpclient = HttpClients.createDefault();
            //指定POST请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);

            //设置请求头
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }
            httpPost.setHeader("X-Caller-Timestamp", dateStr);

            //发送请求 BODY JSON 请求
            StringEntity stringEntity = new StringEntity(jsonObj.toString(), "application/json", CHARACTER_CODE_UTF8);
            httpPost.setEntity(stringEntity);

            httpResponse = httpclient.execute(httpPost);
            //读取响应
            HttpEntity entity = httpResponse.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity, CHARACTER_CODE_UTF8);
                log.info(result);
                return new CloseableHttpEntity(httpResponse.getStatusLine().getStatusCode(), result == null? null:JSONObject.parseObject(result));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpclient != null) {
                try {
                    httpclient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static CloseableHttpEntity sendHttpPost(String url, List<BasicNameValuePair> content) {
        //构建HttpClient实例
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        try {
            SSLContext sslContext = SSLContextBuilder.create().useProtocol(SSLConnectionSocketFactory.SSL).loadTrustMaterial((x, y) -> true).build();
            httpClient = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setSSLContext(sslContext).setSSLHostnameVerifier((x, y) -> true).build();
            //指定POST请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);

            //设置请求头
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                httpPost.setHeader(entry.getKey(), entry.getValue());
            }


            //包装请求体
            List<NameValuePair> params = new ArrayList<>();
            params.add(new BasicNameValuePair("partnerID", partnerId));
            params.addAll(content);
            HttpEntity request = new UrlEncodedFormEntity(params, CHARACTER_CODE_UTF8);

            //发送请求
            httpPost.setEntity(request);

            httpResponse = httpClient.execute(httpPost);

            //读取响应
            HttpEntity entity = httpResponse.getEntity();
            if (entity != null) {
                String result = EntityUtils.toString(entity, CHARACTER_CODE_UTF8);
                System.out.println(result);
                log.info(result);
                return new CloseableHttpEntity(httpResponse.getStatusLine().getStatusCode(), result == null? null:JSONObject.parseObject(result));
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("API HTTP POST UnsupportedEncodingException 请求异常 url={" + url + "}; error = " +e.getMessage() );
        } catch (IOException e) {
            e.printStackTrace();
            log.error("API HTTP POST IOException 请求异常 url={" + url + "}; error = " +e.getMessage() );
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            log.error("API HTTP POST NoSuchAlgorithmException 请求异常 url={" + url + "}; error = " +e.getMessage() );
        } catch (KeyStoreException e) {
            e.printStackTrace();
            log.error("API HTTP POST KeyStoreException 请求异常 url={" + url + "}; error = " +e.getMessage() );
        } catch (KeyManagementException e) {
            e.printStackTrace();
            log.error("API HTTP POST KeyManagementException 请求异常 url={" + url + "}; error = " +e.getMessage() );
        } finally {
            if (httpClient != null) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String generateUUID() {
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    public static void main(String[] args) {
        Order order = new Order();
        order.setNumber("ORD20201022001");

        List<OrderDetails> orders = new ArrayList<>();
        OrderDetails orderDetail = new OrderDetails();
        orderDetail.setProductName("药品");
        orderDetail.setPrice(123.4);


        Waybill waybill = new Waybill();
        waybill.setExpressTypeId("12");
        waybill.setTemperatureRange("1");
        waybill.setWaybillRemark("加速送快递");
        waybill.setContact("小明");
        waybill.setMobile("13410934014");
        waybill.setProvince("上海市");
        waybill.setCity("上海市");
        waybill.setCounty("徐汇区");
        waybill.setAddress("虹口足球场");


        JSONObject msgDataObj = ExpressOrderInfoUtils.generateWaybillOrder(order, orders, waybill);
        String msgData = msgDataObj.toString();
        Long timestamp = System.currentTimeMillis();
        String code = FqConstants.SF_ORDER_SEND_CODE;
        String msgDigest = ExpressOrderInfoUtils.generateSfDigest(msgData, timestamp, code);

        List<BasicNameValuePair> content = new ArrayList<>();
        content.add(new BasicNameValuePair("requestID", generateUUID()));
        content.add(new BasicNameValuePair("serviceCode", generateUUID()));
        content.add(new BasicNameValuePair("timestamp", String.valueOf(timestamp)));
        content.add(new BasicNameValuePair("msgDigest", msgDigest));
        content.add(new BasicNameValuePair("msgData", msgData));

        sendHttpPost(FqConstants.SF_ORDER_SEND_URL, content);
    }

}
