package com.ym.mec.thirdparty.message.vendors;

import java.io.IOException;
import java.util.HashMap;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.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.ym.mec.thirdparty.exception.ThirdpartyException;
import com.ym.mec.thirdparty.message.MessageSenderPlugin;
import com.ym.mec.util.http.HttpUtil;

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

	@Value("${push.jiguang.appKey:1}")
	private String appKey;

	@Value("${push.jiguang.masterSecret:1}")
	private String masterSecret;

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

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

	@Value("${push.jiguang.reqURL:1}")
	private String reqURL;// 请求极光地址

	/**
	 * 组装推送Json串
	 *
	 * @param alias 别名推送
	 * @param alert 消息
	 * @param content 消息内容
	 * @return json对象
	 */
	private JSONObject generateJson(String[] alias, String alert, String content, String url) {
		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("builder_id", 1);
		JSONObject android_extras = new JSONObject();// android额外参数
		android_extras.put("type", "infomation");
		android_extras.put("url", url);
		android.put("extras", android_extras);

		JSONObject ios = new JSONObject();// ios通知内容
		ios.put("alert", alert);
		ios.put("sound", "default");
		ios.put("badge", "+1");
		JSONObject ios_extras = new JSONObject();// ios额外参数
		ios_extras.put("type", "infomation");
		ios_extras.put("url", 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");

		JSONObject options = new JSONObject();// 设置参数
		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 base64_auth_string = encryptBASE64(this.appKey + ":" + this.masterSecret);
		String authorization = "Basic " + base64_auth_string;
		return sendPostRequest(generateJson(alias, alert, content, url).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) throws IOException {
		String[] alias = { receiver };
		String result = this.push(alias, subject, content, url);
		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) throws IOException {
		String result = this.push(receivers, subject, content, url);
		JSONObject json = JSONObject.parseObject(result);
		if (json.containsKey("error")) {
			JSONObject jsonObject = json.getJSONObject("error");
			throw new ThirdpartyException(jsonObject.get("message").toString());
		}
		return true;
	}

	public void setAppKey(String appKey) {
		this.appKey = appKey;
	}

	public void setMasterSecret(String masterSecret) {
		this.masterSecret = masterSecret;
	}

	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;
	}

}
