package org.dromara.settlement.common.bank.jiaotong;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.alibaba.fastjson.JSONObject;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.settlement.api.domain.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class JiaoTongUtil {
	private static final Logger log = LoggerFactory.getLogger(JiaoTongUtil.class);

	private static class SingletonHolder {
		private static final JiaoTongUtil INSTANCE = new JiaoTongUtil();
	}

	private JiaoTongUtil() {
	}

	public static final JiaoTongUtil getInstance() {
		return SingletonHolder.INSTANCE;
	}

	public static void main(String[] args) {
		System.out.println(5%2);
	}

	public Result<String> request(JiaoTongConfig config, String funcode, String reqid, String body) {
		// AES加密
		String request = "";
		String res = "";
		try {
			StringBuilder sb = new StringBuilder();
			sb.append("<ap>");
			sb.append("<head>");
			sb.append("<tr_code>" + funcode + "</tr_code>");
			sb.append("<corp_no>" + config.CorpNo + "</corp_no>");
			sb.append("<user_no>" + config.UserNo + "</user_no>");
			sb.append("<req_no>" + reqid + "</req_no>");
			Date curDate = new Date();
			sb.append("<tr_acdt>"
					+ DateUtils.parseDateToString(DateUtils.YYYY_MM_DD, curDate).replace("-", "")
					+ "</tr_acdt>");
			sb.append("<tr_time>"
					+ DateUtils.parseDateToString(DateUtils.HH_mm_ss, curDate).replace("-", "")
					+ "</tr_time>");
			sb.append("<atom_tr_count>1</atom_tr_count>");
			sb.append("<channel>0</channel>");
			sb.append("</head>");
			sb.append("<body>");
			sb.append(body);
			sb.append("</body>");
			sb.append("</ap>");
			request = sb.toString();
			log.info("request: (" + config.URL+"),"+request);
			res = doPostForm(config.URL, request);
			log.info("response: " + res);
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			log.error("交通银行api调用出错（" + JSONObject.toJSONString(config) + "," + funcode + "," + reqid + "," + body
					+ "）：", e);
		}
		Result<String> rtn = new Result<String>();
		rtn.setResult(request);
		rtn.setRtnData(res);
		return rtn;
	}

	public Result<JiaoTongResponse> response(JiaoTongConfig config, String response) {
		// 解密请求
		Result<JiaoTongResponse> rtn = new Result<JiaoTongResponse>();
		if (StringUtils.isBlank(response)) {
			rtn.addError("响应内容不能为空");
			return rtn;
		}
		try {
			Document doc = DocumentHelper.parseText(response);
			Element rootElt = doc.getRootElement();
			Element head = rootElt.element("head");
			JiaoTongResponse data = new JiaoTongResponse();
			data.setData(rootElt.element("body"));
			data.setReqid(head.elementText("req_no"));
			data.setResultcode(head.elementText("particular_code"));
			data.setResultmsg(head.elementText("ans_info") + ":" + head.elementText("particular_info"));
			rtn.setRtnData(data);
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			log.error("解析交通银行响应出错（" + JSONObject.toJSONString(config) + "," + response + "）：", e);
		}
		return rtn;
	}

	// 发送Post请求
	public String doPostForm(String httpUrl, String xml) throws Exception {
		HttpURLConnection connection = null;
		InputStream is = null;
		OutputStream os = null;
		BufferedReader br = null;
		String result = null;
		try {
			if (StringUtils.isNotBlank(httpUrl)) {
				URL url = new URL(httpUrl);
				SSLContext sslcontext;
				sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
				sslcontext.init(null, new TrustManager[] { new X509TrustManager() {
					public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
					}

					public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
					}

					public X509Certificate[] getAcceptedIssuers() {
						return null;
					}
				} }, new java.security.SecureRandom());
				HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
					@Override
					public boolean verify(String s, SSLSession sslsession) {
						System.out.println("WARNING: Hostname is not matched for cert.");
						return true;
					}
				};
				HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
				HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());

				// 新建连接
				connection = (HttpURLConnection) url.openConnection();
				// 设置为POST请求
				connection.setRequestMethod("POST");
				// 设置连接超时时长
				connection.setConnectTimeout(15000);
				// 设置读取超时
				connection.setReadTimeout(60000);
				connection.setInstanceFollowRedirects(true);

				connection.setDoOutput(true);
				connection.setDoInput(true);

				connection.setRequestProperty("Content-Type", "application/xml");
				os = connection.getOutputStream();
				os.write(xml.getBytes("GBK"));
				if (connection.getResponseCode() != 200) {
					is = connection.getErrorStream();
				} else {
					is = connection.getInputStream();
				}
				br = new BufferedReader(new InputStreamReader(is, "GBK"));
				StringBuilder sbf = new StringBuilder();
				String temp = null;
				while ((temp = br.readLine()) != null) {
					sbf.append(temp);
				}
				result = sbf.toString();
			}
		} finally {
			if (null != br) {
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != os) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != is) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			// 关闭连接
			if(connection != null) {
				connection.disconnect();
			}
		}
		return result;
	}

	/**
	 * 解析多域串内容
	 * @author 张涛
	 * @date 2022年7月1日
	 * @param dataStr 多域串内容
	 * @param fieldNum 字段数
	 * @return
	 */
	public List<Map<String,String>> getMutiAreaData(String dataStr,int fieldNum){
		List<Map<String,String>> data = new ArrayList<Map<String,String>>();
		if (StringUtils.isNotBlank(dataStr)) {
			String[] dataArr = dataStr.split("\\|");
			if (dataArr.length > fieldNum) {
				//key:字段索引  value:字段名称
				Map<Integer, String> fieldIndex = new HashMap<Integer, String>();
				Map<String,String> rowData = null;
				for (int i = 0,len = dataArr.length; i < len; i++) {
					if (i < fieldNum) {
						fieldIndex.put(i, dataArr[i]);
					}else {
						Integer index = i % fieldNum;//当前字段索引
						if (index == 0) {
							rowData = new HashMap<String, String>();
							data.add(rowData);
						}
						rowData.put(fieldIndex.get(index), dataArr[i]);
					}
				}
			}
		}
		return data;
	}
}
