package com.palmnest.application.core.util;

import cn.superdesk.libs.common.json.JsonUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.palmnest.application.Constants;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

@Slf4j
public class WeiXinHelper {

	/**
	 * 获取access_token
	 *
	 * @param appId
	 * @param secret
	 * @return
	 * @throws IOException
	 * @throws KeyManagementException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 */
	private static String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";

	private static String USER_URL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=";

	private static String NEXT_USER_URL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESSTOKEN&next_openid=NEXT_OPENID";

	private static String GET_ALL_TEMPLATE_URL = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN";

	// 临时二维码  
	private final static String QR_SCENE           = "QR_SCENE";
	// 永久二维码  
	private final static String QR_LIMIT_SCENE     = "QR_LIMIT_SCENE";
	// 永久二维码(字符串)  
	private final static String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
	// 创建二维码  
	private final static String CREATE_TICKET_PATH = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=";
	// 通过ticket换取二维码  
	private final static String SHOWQRCODE_PATH    = "https://mp.weixin.qq.com/cgi-bin/showqrcode";
	//发送模板消息
	public final static  String TEMPLATE_SEND_URL  = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN";

	public static String getToken(String appId, String secret) throws IOException, KeyManagementException, NoSuchAlgorithmException, NoSuchProviderException {
		try {
			Map<String, Object> paramMap = new HashMap<>();
			paramMap.put("grant_type", "client_credential");
			paramMap.put("appid", appId);
			paramMap.put("secret", secret);
			String jsonStr = HttpKit.HttpClientPost(JSONObject.toJSONString(paramMap), Constants.STABLE_ACCESS_TOKEN_URL);
			log.info("获取appid: {} ,access_token返回结果：{}", appId,  jsonStr);
			Map<String, Object> map = JSONObject.parseObject(jsonStr);
			if (map.containsKey("access_token")) {
				return map.get("access_token").toString();
			}
		} catch (Exception e) {
			log.info("获取access_token失败", e);
			//输出返回结果
		}
		return "";
	}


	//获取关注列表;
	public static List<String> getUserList(String accessToken) {
		StringBuffer bufferRes = new StringBuffer();
		List<String> users = null;
		try {
			URL realUrl = new URL(USER_URL + accessToken);
			HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
			// 请求方式
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestProperty("Content-Type", "application/json");
			conn.connect();
			// 获取URLConnection对象对应的输入流
			InputStream in = conn.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String valueString = null;
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			System.out.println(bufferRes);
			in.close();
			if (conn != null) {
				// 关闭连接
				conn.disconnect();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		//将返回的字符串转换成json
		JSONObject jsonObject = JSONObject.parseObject(bufferRes.toString());
		//解析json中表示openid的列表
		JSONObject data = (JSONObject) jsonObject.get("data");
		if (data != null) {
			//将openid列表转化成数组保存
			//users = new ArrayList<String>(data.(("openid"));
			JSONArray array = (JSONArray) data.get("openid");
			String js = array.toJSONString();
			users = JSONObject.parseArray(js, String.class);
			//获取关注者总数
			int count = Integer.parseInt(jsonObject.get("total").toString());
			if (count > 1000) {
				JSONObject object = jsonObject;
				String next_openid = null;
				JSONObject ob_data = null;
				//大于10000需要多次获取，或许次数为count/10000----------2021-12-28试了貌似大于1000个也能从第一个接口中获取了，看了公众号里面是10000个；不知道是写代码的人漏了一个0，还是公众号原先是1000
				for (int i = 0; i < count / 10000; i++) {
					//解析出下次获取的启示openid
					next_openid = object.get("next_openid").toString();
					object = getUserJson(next_openid,accessToken);
					ob_data = (JSONObject) object.get("data");
					if(null != ob_data){
						JSONArray array1 = (JSONArray) ob_data.get("openid");
						String js1 = array1.toJSONString();
						//将多次获取的openid添加到同一个数组
						users.addAll(JSONObject.parseArray(js1, String.class));
					}
				}
			}
		}
		return users;
	}
	
	public static void main(String[] args) {
		String token = "52_98eTVTUjq3IREX1jBFADmQHSr7_Y5ZQ-Z9jyK14OjMJjymg8jxlmIezlaGSgtBxTgd21FhpW1Bsv2LeXsKxEWoJyPF2JD2K7IZhb2Le37OvGmwHVeDYS0gKU09XAy-e5Z3XyzSpgCi0iiRfYFFHfAAAPPR";
		List<String> list = getUserList(token);
		System.out.println(JsonUtils.toJson(list));
		
	}

	// 连续获取关注列表;
	public static JSONObject getUserJson(String next_openid, String accessToken) {
		StringBuffer bufferRes = new StringBuffer();
		try {
			URL realUrl = new URL(NEXT_USER_URL.replace("ACCESSTOKEN",
					accessToken).replace("NEXT_OPENID", next_openid));
			HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
			// 请求方式
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setRequestMethod("GET");
			conn.setUseCaches(false);
			conn.setInstanceFollowRedirects(true);
			conn.setRequestProperty("Content-Type", "application/json");
			conn.connect();
			// 获取URLConnection对象对应的输入流
			InputStream in = conn.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in, "UTF-8"));
			String valueString = null;
			while ((valueString = read.readLine()) != null) {
				bufferRes.append(valueString);
			}
			
			System.out.println(bufferRes);
			in.close();
			if (conn != null) {
				// 关闭连接
				conn.disconnect();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		JSONObject jsonObject = JSONObject.parseObject(bufferRes.toString());
		return jsonObject;
	}

	/**
	 * 获取所有关注列表
	 * @param accessToken
	 * @return
	 */
//	public static List<Template> getAllTemplates(String accessToken) {
//		List<Template> templates = new ArrayList<Template>();
//		JSONObject jsonResult = HttpPostUtil.doHttpPostJson(
//				GET_ALL_TEMPLATE_URL.replace("ACCESS_TOKEN", accessToken), "");
//		if (jsonResult.containsKey("template_list")) {
//			JSONArray object = (JSONArray) jsonResult.get("template_list");
//			String json = object.toJSONString();
//			System.out.println(json);
//			templates = JSONArray.parseArray(json, Template.class);
//		}
//		return templates;
//	}

	/**
	 * 创建临时带参数二维码
	 *
	 * @param accessToken
	 * @param sceneId     场景Id
	 * @return
	 * @expireSeconds 该二维码有效时间，以秒为单位。 最大不超过2592000（即30天），此字段如果不填，则默认有效期为30秒。
	 */
	public static JSONObject createTempTicket(String accessToken, String expireSeconds, int sceneId) {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put("access_token", accessToken);
		Map<String, Integer> intMap = new HashMap<String, Integer>();
		intMap.put("scene_id", sceneId);
		Map<String, Map<String, Integer>> mapMap = new HashMap<String, Map<String, Integer>>();
		mapMap.put("scene", intMap);
		//
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		paramsMap.put("expire_seconds", expireSeconds);
		paramsMap.put("action_name", QR_SCENE);
		paramsMap.put("action_info", mapMap);
		String data = JSONObject.toJSONString(paramsMap);

		return HttpPostUtil.doHttpPostJson(CREATE_TICKET_PATH + accessToken, data);

	}

	/**
	 * 创建永久带参数二维码
	 *
	 * @param accessToken
	 * @param sceneId     场景Id
	 * @return
	 */
	public static JSONObject createTicket(String accessToken, int sceneId) {
		TreeMap<String, String> params = new TreeMap<String, String>();
		params.put("access_token", accessToken);
		Map<String, Integer> intMap = new HashMap<String, Integer>();
		intMap.put("scene_id", sceneId);
		Map<String, Map<String, Integer>> mapMap = new HashMap<String, Map<String, Integer>>();
		mapMap.put("scene", intMap);
		//
		Map<String, Object> paramsMap = new HashMap<String, Object>();
		//paramsMap.put("expire_seconds", expireSeconds);
		paramsMap.put("action_name", QR_LIMIT_SCENE);
		paramsMap.put("action_info", mapMap);
		String data = JSONObject.toJSONString(paramsMap);

		return HttpPostUtil.doHttpPostJson(CREATE_TICKET_PATH + accessToken, data);

	}


//	public static void sendTemplateMsg(WechatTemplateMsg msg) {
//
//		
//	}
}
