package cn.com.capcloud.core.util;

import cn.com.capcloud.ccui.core.common.json.JackJSON;
import org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpPut;
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.*;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicNameValuePair;
import org.apache.hc.core5.net.URIBuilder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class KHCHttpUtils {
	public static String postFormData(String url, Map<String, Object> formData) throws Exception {
		return postFormData(url, formData, null);
	}

	public static String postFormData(String url, Map<String, Object> formData, String token) throws Exception {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		List<NameValuePair> nvps = new ArrayList<>();
		for (String key : formData.keySet()) {
			nvps.add(new BasicNameValuePair(key, String.valueOf(formData.get(key))));
		}
		if (token != null && token.length() > 0) {
			httpPost.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}
		httpPost.setEntity(new UrlEncodedFormEntity(nvps));
		CloseableHttpResponse response = httpClient.execute(httpPost);
		HttpEntity entity = response.getEntity();

		if (response.getCode() == HttpStatus.SC_OK) {
			return EntityUtils.toString(response.getEntity());
		} else {
			// 构建详细的错误消息
			String errorMessage = String.format(
					"\n\t-HTTP Request Error:\n\t-Status Code: %d\n\t-URL: %s\n\t-Request Body: %s",
					response.getCode(), url, JackJSON.toJSONString(formData));
			throw new Exception(errorMessage);
		}
	}

	public static String postRawData(String url, String postDataJson) throws Exception {
		return KHCHttpUtils.postRawData(url, postDataJson, null);
	}

	public static String postRawData(String url, String postDataJson, String token) throws Exception {
		// 获取默认配置的 HttpClient
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);

		HttpEntity httpEntity = new StringEntity(postDataJson, ContentType.APPLICATION_JSON);
		httpPost.setEntity(httpEntity);
		if (token != null && token.length() > 0) {
			httpPost.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}
		CloseableHttpResponse response = httpClient.execute(httpPost);
		if (response.getCode() == HttpStatus.SC_OK) {
			return EntityUtils.toString(response.getEntity());
		} else {
			// 构建详细的错误消息
			String errorMessage = String.format(
					"\n\t-HTTP Request Error:\n\t-Status Code: %d\n\t-URL: %s\n\t-Request Body: %s",
					response.getCode(), url, postDataJson);
			throw new Exception(errorMessage);
		}
	}

	public static String putData(String url, String postDataJson, String token) throws Exception {
		// 获取默认配置的 HttpClient
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPut httpPut = new HttpPut(url);
		HttpEntity httpEntity = new StringEntity(postDataJson, ContentType.APPLICATION_JSON);
		httpPut.setEntity(httpEntity);
		if (token != null && token.length() > 0) {
			httpPut.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}
		CloseableHttpResponse response = httpClient.execute(httpPut);
		if (response.getCode() == HttpStatus.SC_OK) {
			return EntityUtils.toString(response.getEntity());
		} else {
			// 构建详细的错误消息
			String errorMessage = String.format(
					"\n\t-HTTP Request Error:\n\t-Status Code: %d\n\t-URL: %s\n\t-Request Body: %s",
					response.getCode(), url, postDataJson);
			throw new Exception(errorMessage);
		}
	}

	public static String deleteData(String url, String postDataJson, String token) throws Exception {
		// 获取默认配置的 HttpClient
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpDelete httpDelete = new HttpDelete(url);
		HttpEntity httpEntity = new StringEntity(postDataJson, ContentType.APPLICATION_JSON);
		httpDelete.setEntity(httpEntity);
		if (token != null && token.length() > 0) {
			httpDelete.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}
		CloseableHttpResponse response = httpClient.execute(httpDelete);

		if (response.getCode() == HttpStatus.SC_OK) {
			return EntityUtils.toString(response.getEntity());
		} else {
			// 构建详细的错误消息
			String errorMessage = String.format(
					"\n\t-HTTP Request Error:\n\t-Status Code: %d\n\t-URL: %s\n\t-Request Body: %s",
					response.getCode(), url, postDataJson);
			throw new Exception(errorMessage);
		}
	}

	public static String get(String url) throws ParseException, IOException {
		return get(url, null, null);
	}

	public static String get(String url, Map<String, String> dataMap) throws ParseException, IOException {
		return get(url, dataMap, null);
	}

	public static String get(String url, Map<String, String> dataMap, String token) throws ParseException, IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		String resultContent = null;
		HttpGet httpGet = new HttpGet(url);

		List<NameValuePair> nvps = new ArrayList<>();
		if (dataMap != null) {
			// GET 请求参数
			for (String key : dataMap.keySet()) {
				nvps.add(new BasicNameValuePair(key, String.valueOf(dataMap.get(key))));
			}
		}
		// 增加到请求 URL 中
		try {
			URI uri = new URIBuilder(new URI(url)).addParameters(nvps).build();
			httpGet.setUri(uri);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
		if (token != null && token.length() > 0) {
			httpGet.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}

		CloseableHttpResponse response = httpclient.execute(httpGet);

		HttpEntity entity = response.getEntity();
		// 获取响应信息
		resultContent = EntityUtils.toString(entity);

		return resultContent;
	}

	public static String downFile(String url, String loaclPathName) throws IOException {
		return downFile(url, loaclPathName, null, null);
	}

	public static String downFile(String url, String loaclPathName, String token) throws IOException {
		return downFile(url, loaclPathName, null, token);
	}

	public static String downFile(String url, String loaclPathName, Map<String, String> dataMap) throws IOException {
		return downFile(url, loaclPathName, dataMap, null);
	}

	public static String downFile(String url, String loaclPathName, Map<String, String> dataMap, String token)
			throws IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		String resultContent = null;
		HttpGet httpGet = new HttpGet(url);

		List<NameValuePair> nvps = new ArrayList<>();
		if (dataMap != null) {
			// GET 请求参数
			for (String key : dataMap.keySet()) {
				nvps.add(new BasicNameValuePair(key, String.valueOf(dataMap.get(key))));
			}
		}

		try {
			URI uri = new URIBuilder(new URI(url)).addParameters(nvps).build();
			httpGet.setUri(uri);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e);
		}
		if (token != null && token.length() > 0) {
			httpGet.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}

		CloseableHttpResponse response = httpclient.execute(httpGet);

		HttpEntity entity = response.getEntity();
		InputStream is = entity.getContent();
		File file = new File(loaclPathName);
		file.getParentFile().mkdirs();
		FileOutputStream fileout = new FileOutputStream(file);
		byte[] buffer = new byte[1024];
		int ch = 0;
		while ((ch = is.read(buffer)) != -1) {
			fileout.write(buffer, 0, ch);
		}
		is.close();
		fileout.flush();
		fileout.close();
		resultContent = loaclPathName;

		return resultContent;
	}

	public static String uploadFile(String fileAllPathAndName, String url, Map<String, String> dataMap, String token)
			throws IOException, ParseException {
		String jsonStr = "";
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		
		//切记不要写这个玩意，不要写不要写不要写！
		//httpPost.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
		//httpPost.addHeader("accept", " application/json");
		
		if (token != null && token.length() > 0) {
			httpPost.addHeader("Authorization", token.startsWith("Bearer ") ? token : "Bearer " + token);
		}
		
		List<NameValuePair> nvps = new ArrayList<>();
		if (dataMap != null) {
			for (String key : dataMap.keySet()) {
				nvps.add(new BasicNameValuePair(key, String.valueOf(dataMap.get(key))));
			}
		}

		
		NameValuePair fileNvp = new BasicNameValuePair("file", fileAllPathAndName);
		HttpEntity entity = httpEntityBuild(fileNvp, nvps);
		
		httpPost.setEntity(entity);
		CloseableHttpResponse response = httpClient.execute(httpPost);
		if (response.getCode() == HttpStatus.SC_OK) {

			jsonStr = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8.displayName());
		}
		return jsonStr;

	}
	
	public static HttpEntity httpEntityBuild(NameValuePair fileNvp, List<NameValuePair> nvps) {
	    File file = new File(fileNvp.getValue());
	    MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.STRICT);
	    if (nvps != null && nvps.size() > 0) {
	        for (NameValuePair nvp : nvps) {
	            builder.addTextBody(nvp.getName(), nvp.getValue(), ContentType.DEFAULT_BINARY);
	        }
	    }
	    builder.addBinaryBody(fileNvp.getName(), file, ContentType.DEFAULT_BINARY, fileNvp.getValue());
	    return builder.build();
	}
	

	// todo 异步post,get、ssl
}
