package com.yonge.toolset.thirdparty.message.provider;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Collectors;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yonge.toolset.base.exception.ThirdpartyException;
import com.yonge.toolset.thirdparty.message.MessageSenderPlugin;
import com.yonge.toolset.utils.http.HttpUtil;

/**
 * 极光推送
 */
@Service
public class JiguangPushPlugin implements MessageSenderPlugin, InitializingBean {

	@Value("${push.jiguang.appKey.student}")
	private String studentAppKey;
	@Value("${push.jiguang.masterSecret.student}")
	private String studentMasterSecret;

	@Value("${push.jiguang.appKey.teacher}")
	private String teacherAppKey;
	@Value("${push.jiguang.masterSecret.teacher}")
	private String teacherMasterSecret;

	@Value("${push.jiguang.appKey.system}")
	private String systemAppKey;
	@Value("${push.jiguang.masterSecret.system}")
	private String systemMasterSecret;

	@Value("${push.jiguang.apns_production:false}")
	private boolean apns_production = true; // 推送环境 True 表示推送生产环境，False 表示要推送开发环境

	@Value("${push.jiguang.time_to_live:86400}")
	private int time_to_live = 86400; // 离线保留时长 秒为单位 默认1天 最大10天

	@Value("${push.jiguang.reqURL:https://api.jpush.cn/v3/push}")
	private String reqURL = "https://api.jpush.cn/v3/push";// 请求极光地址

	public static String getName() {
		return "jiguang";
	}

	/**
	 * 组装推送Json串
	 *
	 * @param alias 别名推送
	 * @param alert 消息
	 * @param content 消息内容
	 * @return json对象
	 */
	private JSONObject generateJson(String[] alias, String alert, String content, String url,String sound,String channelId) {
		JSONObject json = new JSONObject();
		JSONArray platform = new JSONArray();// 平台
		platform.add("android");
		platform.add("ios");

		JSONObject audience = new JSONObject();// 推送目标
		JSONArray aliasJsonArr = new JSONArray();
		for (String alia : alias) {
			aliasJsonArr.add(alia);
		}
		audience.put("alias", aliasJsonArr);

		JSONObject notification = new JSONObject();// 通知内容
		JSONObject android = new JSONObject();// android通知内容
		android.put("alert", alert);
		android.put("sound", sound.split("\\.")[0]);
		JSONObject options = new JSONObject();// 设置参数
		if(StringUtils.isNotEmpty(channelId)){
			JSONObject thirdParty = new JSONObject();
			JSONObject xiaomi = new JSONObject();
			xiaomi.put("distribution","secondary_push");
			xiaomi.put("channel_id",channelId);
			thirdParty.put("xiaomi",xiaomi);
			options.put("third_party_channel",thirdParty);
		}
		android.put("builder_id", 1);
		JSONObject android_extras = new JSONObject();// android额外参数
		android_extras.put("type", "infomation");
		android_extras.put("url", url);
		android_extras.put("memo", url);
		android.put("extras", android_extras);

		JSONObject ios = new JSONObject();// ios通知内容
		ios.put("alert", alert);
		ios.put("sound", sound);
		ios.put("badge", "+1");
		JSONObject ios_extras = new JSONObject();// ios额外参数
		ios_extras.put("type", "infomation");
		ios_extras.put("url", url);
		ios_extras.put("memo", url);
		ios.put("extras", ios_extras);
		notification.put("android", android);
		notification.put("ios", ios);

		JSONObject message = new JSONObject();// 通知消息内容
		message.put("title", alert);
		message.put("msg_content", content);
		message.put("content_type","text");

		options.put("time_to_live", this.time_to_live);
		options.put("apns_production", this.apns_production);

		json.put("platform", platform);
		json.put("audience", audience);
		json.put("notification", notification);
		json.put("options", options);
		json.put("message", message);
		return json;

	}

	/**
	 * 调用极光api
	 * @param alias 推送对象别名
	 * @param alert 推送消息
	 * @param content 推送内容
	 */
	private String push(String[] alias, String alert, String content, String url,String type,String sound,String channelId) {
		String base64_auth_string = "";
		switch (type){
			case "STUDENT":
				base64_auth_string = encryptBASE64(this.studentAppKey + ":" + this.studentMasterSecret);
				break;
			case "TEACHER":
				base64_auth_string = encryptBASE64(this.teacherAppKey + ":" + this.teacherMasterSecret);
				break;
			default:
				base64_auth_string = encryptBASE64(this.systemAppKey + ":" + this.systemMasterSecret);
				break;
		}
		String authorization = "Basic " + base64_auth_string;
		return sendPostRequest(generateJson(alias, alert, content, url,sound,channelId).toString(), authorization);
	}

	/**
	 * 发送Post请求（json格式）
	 *
	 * @param data //封装的json串
	 * @param authorization 验签
	 * @return result 返回一个json字符串
	 */
	private String sendPostRequest(String data, String authorization) {
		String result = "";
		HashMap<String, String> reqHeader = new HashMap<>();
		reqHeader.put("Authorization", authorization.trim());
		try {
			result = HttpUtil.postForHttps(this.reqURL, data, reqHeader);
		} catch (Exception e) {
			throw new ThirdpartyException("HttpUtil Connection Exception", e);
		}
		return result;
	}

	/**
	 * 　　　　* BASE64加密工具
	 */
	private String encryptBASE64(String str) {
		byte[] key = str.getBytes();
		String strs = Base64.encodeBase64String(key);
		return strs;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// 参数检查
		/*if (StringUtils.isBlank(appKey)) {
			throw new RuntimeException("Init parameter [appKey] can not blank");
		}
		if (StringUtils.isBlank(masterSecret)) {
			throw new RuntimeException("Init parameter [masterSecret] can not blank");
		}
		if (StringUtils.isBlank(reqURL)) {
			throw new RuntimeException("Init parameter [reqURL] can not blank");
		}*/
	}

	@Override
	public boolean send(String subject, String content, String receiver, String url, String type,String sound,String channelId) throws IOException {
		String[] alias = { receiver };
		String result = this.push(alias, subject, content, url,type,sound,channelId);
		JSONObject json = JSONObject.parseObject(result);
		if (json.containsKey("error")) {
			JSONObject jsonObject = json.getJSONObject("error");
			throw new ThirdpartyException(jsonObject.get("message").toString());
		}
		return true;
	}

	@Override
	public boolean batchSend(String subject, String content, String[] receivers, String url, String type,String sound,String channelId) throws IOException {
		String result = this.push(receivers, subject, content, url,type,sound,channelId);
		JSONObject json = JSONObject.parseObject(result);
		if (json.containsKey("error")) {
			JSONObject jsonObject = json.getJSONObject("error");
			throw new ThirdpartyException(jsonObject.get("message").toString()+"["+Arrays.stream(receivers).collect(Collectors.joining(","))+"]");
		}
		return true;
	}

	public void setStudentAppKey(String studentAppKey) {
		this.studentAppKey = studentAppKey;
	}

	public void setStudentMasterSecret(String studentMasterSecret) {
		this.studentMasterSecret = studentMasterSecret;
	}

	public void setTeacherAppKey(String teacherAppKey) {
		this.teacherAppKey = teacherAppKey;
	}

	public void setTeacherMasterSecret(String teacherMasterSecret) {
		this.teacherMasterSecret = teacherMasterSecret;
	}

	public String getSystemAppKey() {
		return systemAppKey;
	}

	public void setSystemAppKey(String systemAppKey) {
		this.systemAppKey = systemAppKey;
	}

	public String getSystemMasterSecret() {
		return systemMasterSecret;
	}

	public void setSystemMasterSecret(String systemMasterSecret) {
		this.systemMasterSecret = systemMasterSecret;
	}

	public void setApns_production(boolean apns_production) {
		this.apns_production = apns_production;
	}

	public void setTime_to_live(int time_to_live) {
		this.time_to_live = time_to_live;
	}

	public void setReqURL(String reqURL) {
		this.reqURL = reqURL;
	}

}
