package com.tofly.spire.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author HaiQiu
 * @since 2022/10/24
 */
@Log4j2
public class ApiClient {

    public static String TOKEN = "";

    public static final String UTF_8 = "UTF-8";

    @SneakyThrows
    public static Object get(@Nullable String url, String prams) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpGet = new HttpPost(url + "?" + prams);
        httpGet.addHeader("access_token ", TOKEN);
        CloseableHttpResponse response = client.execute(httpGet);
        return getJsonObject(response);
    }

    @SneakyThrows
    public static Object getGdMap(@Nullable String url, String prams) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url + "?" + prams);
        CloseableHttpResponse response = client.execute(httpGet);
        return getJsonObject(response);
    }

    @SneakyThrows
    public static Object post(@Nullable String url, String json) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        StringEntity se = new StringEntity(json);
        httpPost.setEntity(se);
        CloseableHttpResponse response = client.execute(httpPost);
        return getJsonObject(response);
    }

    @SneakyThrows
    public static Object post(@Nullable String url, Map<String, Object> map) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader(HTTP.CONTENT_TYPE, "application/json");
        List<NameValuePair> nvps = new ArrayList<>();
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
        }
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
        CloseableHttpResponse response = client.execute(httpPost);
        return getJsonObject(response);
    }

    public static Object getReset(@Nullable String url, String params) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add("access_token", TOKEN);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<Object> response = restTemplate.exchange(url + "?" + params, HttpMethod.GET,
                new org.springframework.http.HttpEntity<>(httpHeaders), Object.class);
        Object body = response.getBody();
        log.info("获取返回数据：{}", JSONObject.toJSONString(body));
        return body;
    }

    public static Object postRest(@Nullable String url, Map<String, Object> map) {
        // 创建请求头写入媒体类型为表单
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // 创建表单请求参数
        LinkedMultiValueMap<String, String> valueMap = new LinkedMultiValueMap<>();
        Set<Map.Entry<String, Object>> entries = map.entrySet();
        for (Map.Entry<String, Object> entry : entries) {
            valueMap.add(entry.getKey(), entry.getValue().toString());
        }
        // 组装请求体,泛型为上面的表单map
        org.springframework.http.HttpEntity<LinkedMultiValueMap<String, String>> httpEntity = new org.springframework.http.HttpEntity<>(valueMap, headers);
        // 发起请求并打印结果，以String接收响应结果
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setConnectTimeout(10*1000);
        requestFactory.setReadTimeout(10*1000);
        Object responseJson = new RestTemplate(requestFactory).postForObject(url, httpEntity, Object.class);
        System.out.println(responseJson);
        log.info("获取返回数据：{}", JSONObject.toJSONString(responseJson));
        return responseJson;
    }

    private static JSONObject getJsonObject(CloseableHttpResponse response) throws IOException {
        HttpEntity entity = response.getEntity();
        StatusLine statusLine = response.getStatusLine();
        if (statusLine.getStatusCode() != 200) {
            log.error("请求接口{}", statusLine.getStatusCode());
        }
        String s = readInputStream(entity.getContent());
        JSONObject parse = JSONObject.parseObject(s);
        log.info(parse);
        return parse;
    }


    @SneakyThrows
    private static String readInputStream(InputStream in) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, UTF_8));
        StringBuilder sb = new StringBuilder();
        String temp;
        while ((temp = reader.readLine()) != null) {
            sb.append(temp).append("\n");
        }
        if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\n') {
            sb.setLength(sb.length() - 1);
        }
        reader.close();
        return sb.toString();
    }

//    public static void main(String[] args) {
//        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("username", "hq");
//        jsonObject.put("password", "123");
//        postRest("http://221.182.8.141:10082/tofly-auth/oauth/login", jsonObject);
//    }
}
