package nc.bs.uapbd.bip.workplugin;

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.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
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.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.yonyou.cloud.utils.StringUtils;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.pub.pa.PreAlertObject;
import nc.bs.pub.taskcenter.BgWorkingContext;
import nc.bs.pub.taskcenter.IBackgroundWorkPlugin;
import nc.bs.trade.business.HYSuperDMO;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.util.mmf.framework.base.MMValueCheck;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.pub.BusinessException;

/**
 * 税务云开票成功后回写NCC销售发票表头发票号码字段并回写合同平台【合同开票申请】界面表头已开具发票号码 zhangxinah 适配2312
 */
public class ErpSaleInvoiceToBIPBackgroupWorkPlugin implements IBackgroundWorkPlugin {

	private HYSuperDMO superDMO = null;
	private String baseUrl = "https://www.tkkfbip.com";

	public HYSuperDMO getSuperDMO() {

		if (superDMO == null) {
			superDMO = new HYSuperDMO();
		}

		return superDMO;
	}

	/**
	 * 检查bip参数是否完整
	 * 
	 * @return
	 */
	private Map<String, String> checkBipParam() {

		Map<String, String> map = new HashMap<String, String>();

		String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='BIP-sq' and dr=0 )  and dr=0";

		try {
			DefdocVO[] defdocVOs = (DefdocVO[]) getSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
			if (defdocVOs != null && defdocVOs.length > 0) {
				for (DefdocVO defdocVO : defdocVOs) {

					map.put(defdocVO.getCode().trim(), defdocVO.getName());

				}
			}
		} catch (DAOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return map;

	}

	@Override
	public PreAlertObject executeTask(BgWorkingContext arg0) throws BusinessException {
		// TODO Auto-generated method stub

		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Map<String, String> bipParamMap = checkBipParam();
		if (bipParamMap.isEmpty()) {
			return null;
		}
		baseUrl = bipParamMap.get("baseUrl");
		Map<String, Object> userMap = arg0.getKeyMap();
		String usercustcode = "";
		if (!userMap.isEmpty()) {
			if (userMap.get("code") != null) {
				usercustcode = userMap.get("code").toString();
			}
		}
		String invoiceReceiveUrl = bipParamMap.get("invoiceReceiveUrl");// 开票申请单回传
		if (StringUtils.isEmpty(invoiceReceiveUrl)) {
			return null;
		}

		// 获取开票成功后且为BIP推送过来的发票信息
		String sql_saleinvoice = "select csaleinvoiceid,vdef13 as invoicingcode ,vdef17 as code from   so_saleinvoice  where fstatusflag=2 and nvl(vdef13,'~') not in ('~') and  nvl(vdef17,'~')!='~' and nvl(vdef34,'N') in ('N','~') and nvl(vdef20,'N') in ('Y') ";
		List<Map<String, String>> ll_saleinvoice = (List<Map<String, String>>) new BaseDAO()
				.executeQuery(sql_saleinvoice, new MapListProcessor());
		Gson gson = new Gson();
		if (ll_saleinvoice.isEmpty()) {
			return null;
		}
		try {
			String accessToken = getAccessToken(baseUrl, bipParamMap);
			Map<String, String> tokenParam = new HashMap<>();
			tokenParam.put("access_token", accessToken);
			Map<String, String> headers = new HashMap<String, String>();
			headers.put("Content-Type", "application/json");
			String custUpdateUrl = baseUrl + invoiceReceiveUrl;
			if (accessToken != "") {
				for (Map<String, String> custpkmap : ll_saleinvoice) {

					JSONObject js_apct_detail = new JSONObject();
					js_apct_detail.put("code", custpkmap.get("code"));
					js_apct_detail.put("invoicingCode", custpkmap.get("invoicingcode"));

					String resultString = doSendHttp(custUpdateUrl, "POST", tokenParam, "", headers,
							js_apct_detail.toJSONString());
					Map updateMap = gson.fromJson(resultString, Map.class);
					String updateSql = "";
					if (StringUtils.equals("200", updateMap.get("code").toString())) {// 保存更新成功后需要更新日志表
						updateSql = "update so_saleinvoice set vdef34='Y' ,vdef35='' where csaleinvoiceid='"
								+ custpkmap.get("csaleinvoiceid") + "'";
					} else {
						updateSql = "update so_saleinvoice set vdef34='N' ,vdef35='" + updateMap.get("message")
								+ "' where csaleinvoiceid='" + custpkmap.get("csaleinvoiceid") + "'";
					}
					getSuperDMO().executeUpdateSQL(updateSql);

				}
			}

		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} // 获取BIP的token
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 查询bip 中开户行及银行类型id
	 * 
	 * @param map
	 * @param bipUrl
	 * @return
	 */
	private static Map<String, String> getBIPBankID(HashMap<String, String> map, String bipUrl, String accessToken,
			String bankdocname) {

		Gson gson = new Gson();

		Map<String, String> tokenParam = new HashMap<>();
		tokenParam.put("access_token", accessToken);
		String jsonData = JSON.toJSONString(map);
		String resultString = doSendHttp(bipUrl, "POST", tokenParam, "", new HashMap<>(), jsonData);
//			Map custDetailresult = gson.fromJson(resultString, Map.class);
		JSONObject custDetailresult = JSON.parseObject(resultString);
		if (StringUtils.equals("200", custDetailresult.get("code").toString())) {// 数据存在
			Map<String, Object> dataInfo = (Map<String, Object>) custDetailresult.get("data");
			if (!MMValueCheck.isEmpty(dataInfo.get("recordList"))) {
				List<Map<String, String>> l_record = (List<Map<String, String>>) dataInfo.get("recordList");
				return l_record.get(0);
			} else {
				map.remove("linenumber");
				map.put("name", bankdocname);
				jsonData = JSON.toJSONString(map);
				resultString = doSendHttp(bipUrl, "POST", tokenParam, "", new HashMap<>(), jsonData);
//					 custDetailresult = gson.fromJson(resultString, Map.class);
				custDetailresult = JSON.parseObject(resultString);
				if (StringUtils.equals("200", custDetailresult.get("code").toString())) {// 数据存在
					dataInfo = (Map<String, Object>) custDetailresult.get("data");
					if (!MMValueCheck.isEmpty(dataInfo.get("recordList"))) {
						List<Map<String, String>> l_record = (List<Map<String, String>>) dataInfo.get("recordList");
						return l_record.get(0);
					}
				}
			}
		}
		return null;
	}

	public static String doSendHttp(String baseUrl, String method, Map<String, String> paramMap, String mediaType,
			Map<String, String> headers, String json) {
		HttpURLConnection urlConnection = null;
		InputStream in = null;
		OutputStream out = null;
		BufferedReader bufferedReader = null;
		String result = null;
		try {
			StringBuffer sb = new StringBuffer();
			sb.append(baseUrl);
			if (paramMap != null) {
				sb.append("?");
				for (Map.Entry<String, String> entry : paramMap.entrySet()) {
					String key = entry.getKey();
					String value = entry.getValue();
					sb.append(key + "=" + value).append("&");
					baseUrl = sb.toString().substring(0, sb.toString().length() - 1);
				}
			}
//            log.error("uRL:" + baseUrl);
//            // 打印请求URL和方法
//            log.error("Request URL: " + baseUrl);
//            log.error("Request Method: " + method);
			URL urlobj = new URL(baseUrl);
			if ("https".equalsIgnoreCase(urlobj.getProtocol())) {// 判定网址是否信任，不信任则调用忽略信任工具类SslUtil
				IgnoreSslUtil.ignoreSsl();
			}
			urlConnection = (HttpURLConnection) urlobj.openConnection();
			urlConnection.setConnectTimeout(50000);
			urlConnection.setRequestMethod(method);
			urlConnection.setDoInput(true);
			urlConnection.setUseCaches(false);
			// 如果设置了自定义头，则打印它们
			if (headers != null && !headers.isEmpty()) {
				for (Map.Entry<String, String> entry : headers.entrySet()) {
					urlConnection.addRequestProperty(entry.getKey(), entry.getValue());
//                    log.error("Request Header: " + entry.getKey() + ": " + entry.getValue());
				}
			}
			if (json != null && json.length() > 0) {
//                log.error("Request Body: " + json);
				urlConnection.setDoInput(true);
				urlConnection.setDoOutput(true);
				out = urlConnection.getOutputStream();
				out.write(json.getBytes("utf-8"));
				out.flush();
			}
			int resCode = urlConnection.getResponseCode();
			String ecod = urlConnection.getContentEncoding();
			if (resCode == HttpURLConnection.HTTP_OK || resCode == HttpURLConnection.HTTP_CREATED
					|| resCode == HttpURLConnection.HTTP_ACCEPTED) {
				if (StringUtils.isNotEmpty(ecod) && ecod.equals("gzip")) {
					in = new GZIPInputStream(urlConnection.getInputStream());
				} else {
					in = urlConnection.getInputStream();
				}
			} else {
				in = urlConnection.getErrorStream();
			}
			bufferedReader = new BufferedReader(new InputStreamReader(in, "utf-8"));
			StringBuffer temp = new StringBuffer();
			String line = bufferedReader.readLine();
			while (line != null) {
				temp.append(line).append("\r\n");
				line = bufferedReader.readLine();
			}
			if (ecod == null || ecod.equals("gzip")) {
				ecod = Charset.forName("utf-8").name();
			}
			result = new String(temp.toString().getBytes("utf-8"), ecod);
		} catch (Exception e) {
			JSONObject js = new JSONObject();
			js.put("", -1);
			js.put("message", "调用外系统接口失败：" + e.getMessage());
			result = js.toString();
			e.printStackTrace();
		} finally {
			if (null != bufferedReader) {
				try {
					bufferedReader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			urlConnection.disconnect();
		}
		return result;
	}

//	private String createCustBankMap(Map<String,String> map,String access_token) {
//		Gson gson = new Gson();
//		//获取BIP中的客户详情
//		String custcode=map.get("custcode");
//		String custurl=baseUrl+"/yonbip/digitalModel/merchant/detail?access_token="+access_token;
//		HashMap<String, String> custMap = new HashMap<String, String>();
//		custMap.put("code", custcode);
//		try {
//			String custdetailString=doGet(custurl,custMap);
//			
//			Map custDetailresult = gson.fromJson(custdetailString, Map.class);
//			if (StringUtils.equals("200", custDetailresult.get("code").toString())) {//客户存在
//				
//				Map<String, Object> dataInfo = (Map<String, Object>) custDetailresult.get("data");
//				
//				if (!MMValueCheck.isEmpty(dataInfo.get("merchantAgentFinancialInfos"))){//客户中已经存在银行账户
//					
//				}else {
//					
//				}
//				
//			}
//			
//			
//			//开户行
//			String bankdoccode=map.get("bankdoccode");
//			HashMap<String, Object> paramap  = new HashMap<String, Object>();
//			paramap.put("pageIndex", 0);
//			paramap.put("pageSize", 10);
//			paramap.put("linenumber", bankdoccode);
//			String url=baseUrl+"/yonbip/digitalModel/bankdot/list?access_token="+access_token;
//			
//			String responseString=doPost(url,paramap);
//			
//			Map result = gson.fromJson(responseString, Map.class);
//			
//		} catch (IOException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
//		
//	}

	private String getAccessToken(String baseUrl, Map<String, String> bipParamMap)
			throws NoSuchAlgorithmException, InvalidKeyException, IOException {
		String tokenUrl = baseUrl + "/iuap-api-auth/open-auth/selfAppAuth/getAccessToken";
//		String appKey = "f10c4bf17b1d4e1fb08eb82bf8540eab";
		String appKey = bipParamMap.get("appKey");

//		String appSecret = "71dc2a58ca378c1a1143231a62e73e75a60e9236";
		String appSecret = bipParamMap.get("appSecret");
		String accessToken = "";
		Map<String, String> params = new HashMap<>();

		params.put("appKey", appKey);
		String timestamp = String.valueOf(System.currentTimeMillis());
		params.put("timestamp", timestamp);
		// 计算签名
		Map<String, String> treeMap;
		if (params instanceof TreeMap) {
			treeMap = params;
		} else {
			treeMap = new TreeMap<>(params);
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (Map.Entry<String, String> entry : treeMap.entrySet()) {
			stringBuilder.append(entry.getKey()).append(entry.getValue());
		}
		Mac mac = Mac.getInstance("HmacSHA256");

		mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
		byte[] signData = mac.doFinal(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
		String base64String = Base64.getEncoder().encodeToString(signData);
		String signature = URLEncoder.encode(base64String, "UTF-8");
		params.put("signature", signature);

		String responseString = doGet(tokenUrl, params);

		Gson gson = new Gson();
		Map result = gson.fromJson(responseString, Map.class);
		if (StringUtils.equals("00000", result.get("code").toString())) {
			Map<String, Object> tokenInfo = (Map<String, Object>) result.get("data");
			accessToken = (String) tokenInfo.get("access_token");

		}

		return accessToken;
	}

	private String doPost(String requestUrl, JSONObject jsonObject) throws IOException {
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(500);
		cm.setDefaultMaxPerRoute(50);

		RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时
				.setConnectTimeout(5000) // 连接建立超时
				.setSocketTimeout(20000) // 等待响应超时
				.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();

		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
				.setDefaultRequestConfig(globalConfig).build();
		HttpPost post = new HttpPost(requestUrl);
		post.setHeader("Content-Type", "application/json;charset=UTF-8");
		post.setEntity(new StringEntity(JSONObject.toJSONString(jsonObject), "utf-8"));
		String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity()));
		return responseString;

	}

	private String doPost(String requestUrl, Map<String, Object> param) throws IOException {
		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
		cm.setMaxTotal(500);
		cm.setDefaultMaxPerRoute(50);

		RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时
				.setConnectTimeout(5000) // 连接建立超时
				.setSocketTimeout(20000) // 等待响应超时
				.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();

		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
				.setDefaultRequestConfig(globalConfig).build();
		HttpPost post = new HttpPost(requestUrl);
		post.setHeader("Content-Type", "application/json;charset=UTF-8");
		post.setEntity(new StringEntity(JSONObject.toJSONString(param), "utf-8"));
		String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity()));
		return responseString;

	}

	private static String doGet(String path, Map<String, String> params) throws IOException {
		HttpURLConnection conn = null;
		InputStream is = null;
		BufferedReader br = null;
		StringBuilder result = new StringBuilder();
		try {
			if (params != null) {
				String paramStr = "";
				for (String key : params.keySet()) {
					if (!paramStr.isEmpty()) {
						paramStr += '&';
					}
					paramStr += key + '=' + params.get(key);
				}

				if (path.indexOf('?') > 0) {
					path += '&' + paramStr;
				} else {
					path += '?' + paramStr;
				}
			}
			// 创建远程url连接对象
			URL url = new URL(path);
			if ("https".equalsIgnoreCase(url.getProtocol())) {// 判定网址是否信任，不信任则调用忽略信任工具类SslUtil
				IgnoreSslUtil.ignoreSsl();
			}
			// 通过远程url连接对象打开一个连接，强转成HTTPURLConnection类
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			// 设置连接超时时间和读取超时时间
			conn.setConnectTimeout(120000);
			conn.setReadTimeout(120000);
			conn.setRequestProperty("Accept", "application/json");
			// 发送请求
			conn.connect();
			// 通过conn取得输入流，并使用Reader读取
			if (200 == conn.getResponseCode()) {
				is = conn.getInputStream();
				br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				String line;
				while ((line = br.readLine()) != null) {
					result.append(line);
					System.out.println(line);
				}
			} else {
				System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
//        finally {
//            try {
//                if (br != null) {
//                    br.close();
//                }
//                if (is != null) {
//                    is.close();
//                }
//            } catch (IOException ioe) {
//                ioe.printStackTrace();
//            }
//            conn.disconnect();
//        }
		return result.toString();
	}

//    private String doGet(String requestUrl, Map<String, String> paramMap) throws IOException {
//		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
//		cm.setMaxTotal(500);
//		cm.setDefaultMaxPerRoute(50);
//
//		RequestConfig globalConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // 连接池获取连接超时
//				.setConnectTimeout(5000) // 连接建立超时
//				.setSocketTimeout(20000) // 等待响应超时
//				.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
//
//		CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(cm)
//				.setDefaultRequestConfig(globalConfig).build();
//		StringBuilder param = new StringBuilder("?");
//		if (paramMap != null) {
//			for (Map.Entry<String, String> entry : paramMap.entrySet()) {
//				param.append(entry.getKey());
//				param.append("=");
//				param.append(entry.getValue());
//				param.append("&");
//			}
//			param.deleteCharAt(param.length() - 1);
//		}
//		String url = requestUrl + param;
//		HttpGet get = new HttpGet(url);
//		String responseString = httpClient.execute(get, response -> EntityUtils.toString(response.getEntity()));
//		get.releaseConnection();
//		return responseString;
//	}

}
