
package org.tio.sitexxx.service.service.jpush;

import cn.hutool.core.util.StrUtil;
import cn.jiguang.sdk.api.PushApi;
import cn.jiguang.sdk.bean.push.PushSendParam;
import cn.jiguang.sdk.bean.push.PushSendResult;
import cn.jiguang.sdk.bean.push.audience.Audience;
import cn.jiguang.sdk.bean.push.message.notification.NotificationMessage;
import cn.jiguang.sdk.bean.push.options.Options;
import cn.jiguang.sdk.enums.platform.Platform;
import com.oppo.push.server.Environment;
import com.oppo.push.server.Notification;
import com.oppo.push.server.Target;
import com.xiaomi.xmpush.server.Constants;
import com.xiaomi.xmpush.server.Message;
import com.xiaomi.xmpush.server.Result;
import com.xiaomi.xmpush.server.Sender;
import org.tio.sitexxx.service.service.jpush.honor.Honor;
import org.tio.jfinal.plugin.activerecord.Record;
import org.tio.sitexxx.service.service.jpush.huawei.Huawei;

import java.util.*;

/**
 * 推送服务
 * @author xufei
 * 2020年09月25日 下午5:57:32
 */
public class JPushService {
	public static final boolean IS_DEBUG = false;

	public static final JPushService me	= new JPushService();

	private static PushApi pushApi;

	public static PushApi getPushApi(){
		if (pushApi == null) {
			pushApi = new PushApi.Builder()
					.setAppKey("6a59cc712167aa5917deecf7")
					.setMasterSecret("0a3ffb228f37895807cdfa6d")
					.build();
		}
		return pushApi;
	}

	/**
	 * 处理更多推送
	 * @param ids 序号列表
	 * @param title 标题
	 * @param msg 消息内容
	 * @param extra 额外信息
	 */
	public void handlerMorePush(List<Record> ids, String title, String msg, Map<String, String> extra) {
		List<String> jiguangIds = new ArrayList<>();
		List<String> xiaomiIds = new ArrayList<>();
		List<String> huaweiIds = new ArrayList<>();
		List<String> vivoIds = new ArrayList<>();
		List<String> honorIds = new ArrayList<>();
		List<String> oppoIds = new ArrayList<>();
		for (Record id : ids) {
			String type = id.getStr("type");
			String token = id.getStr("token");
			String regId = id.getStr("regid");
			if (StrUtil.isEmpty(type) || StrUtil.isEmpty(token)) {
				if (StrUtil.isNotEmpty(regId)) {
					jiguangIds.add(regId);
				}
			} else if (StrUtil.isNotEmpty(token)){
				switch (type) {
					case Push.HUAWEI:
						huaweiIds.add(token);
						break;
					case Push.XIAOMI:
						xiaomiIds.add(token);
						break;
					case Push.VIVO:
						vivoIds.add(token);
						break;
					case Push.HONOR:
						honorIds.add(token);
						break;
					case Push.OPPO:
						oppoIds.add(token);
						break;
				}
			}
		}
		if (!jiguangIds.isEmpty()) {
			int size = jiguangIds.size();
			for (int i = 0; i < size; i += 999) {
				int end = Math.min(i + 999, size);
				initJiGuang(jiguangIds.subList(i, end), title, msg, extra);
			}
		}
		if (!xiaomiIds.isEmpty()) {
			int size = xiaomiIds.size();
			if (size == 1) {
				initXiaomi(xiaomiIds, title, msg, extra);
			} else {
				for (int i = 0; i < size; i += 999) {
					int end = Math.min(i + 999, size);
					initXiaomi(xiaomiIds.subList(i, end), title, msg, extra);
				}
			}
		}
		if (!huaweiIds.isEmpty()) {
			int size = huaweiIds.size();
			for (int i = 0; i < size; i += 999) {
				int end = Math.min(i + 999, size);
				try {
					Huawei.send(huaweiIds.subList(i, end), title, msg);
				} catch (Exception e){
					e.printStackTrace();
				}
			}
		}
		if (!vivoIds.isEmpty()) {
			int size = vivoIds.size();
			if (size == 1) {
				try {
					initVivo(vivoIds.get(0), title, msg, extra);
				} catch (Exception e){
					e.printStackTrace();
				}
			} else {
				for (int i = 0; i < size; i += 999) {
					int end = Math.min(i + 999, size);
					try {
						initVivo(vivoIds.subList(i, end), title, msg, extra);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
			}
		}
		if (!oppoIds.isEmpty()) {
			int size = oppoIds.size();
			if (size == 1) {
				try {
					initOppo(oppoIds.get(0), title, msg);
				} catch (Exception e){
					e.printStackTrace();
				}
			} else {
				for (int i = 0; i < size; i += 999) {
					int end = Math.min(i + 999, size);
					try {
						initOppo(oppoIds.subList(i, end), title, msg);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
			}
		}
		if (!honorIds.isEmpty()) {
			int size = honorIds.size();
			if (size == 1) {
				try {
					Honor.send(honorIds.get(0), title, msg);
				} catch (Exception e){
					e.printStackTrace();
				}
			} else {
				for (int i = 0; i < size; i += 999) {
					int end = Math.min(i + 999, size);
					try {
						Honor.send(honorIds.subList(i, end), title, msg);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * 注册id方式初始化-列表
	 * 华为:ok oppo:ok 极光:ok 小米:ok vivo:ok
	 * @param type 类型
	 * @param token 令牌
	 * @param regId 注册序号
	 * @param title 标题
	 * @param extras 额外信息
	 * @param msg 信息
	 * @return
	 * @author xufei
	 * 2020年9月24日 下午6:28:00
	 */
	public void handlerPush(String type, String token, String regId, String title, String msg, Map<String, String> extras) {
		List<String> ids = new ArrayList<>();
		if (StrUtil.isEmpty(type)) {
			type = "";
		}
		switch (type){
			case Push.XIAOMI:
				if (StrUtil.isNotBlank(token)) {
					ids.add(token);
					initXiaomi(ids, title, msg, extras);
				}
				break;
			case Push.VIVO:
				if (StrUtil.isNotBlank(token)) {
					try {
						initVivo(token, title, msg, extras);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
				break;
			case Push.OPPO:
				if (StrUtil.isNotBlank(token)) {
					try {
						initOppo(token, title, msg);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
				break;
			case Push.HUAWEI:
				if (StrUtil.isNotBlank(token)) {
					try {
						Huawei.send(token, title, msg);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
				break;
			case Push.HONOR:
				if (StrUtil.isNotBlank(token)) {
					try {
						Honor.send(token, title, msg);
					} catch (Exception e){
						e.printStackTrace();
					}
				}
				break;
			default:
				if (StrUtil.isNotBlank(regId)) {
					ids.add(regId);
					initJiGuang(ids, title, msg, extras);
				}
				break;
		}
	}

	/**
	 * 极光推送 ok
	 * @param regIds 注册序号
	 * @param msg 消息
	 * @param extras 额外数据
	 * @param title 标题
	 */
	private void initJiGuang(List<String> regIds, String title, String msg, Map<String, String> extras){
		PushSendParam param = new PushSendParam();
		// 通知内容
		NotificationMessage.Android android = new NotificationMessage.Android();
		android.setAlert(msg);
		android.setTitle(title);
		android.setChannelId("default_developer");
		android.setBadgeAddNumber(1);

		NotificationMessage.IOS iOS = new NotificationMessage.IOS();
		Map<String, String> iOSAlert = new HashMap<>();
		iOSAlert.put("title", title);
		iOSAlert.put("body",msg);
		iOS.setAlert(iOSAlert);
		iOS.setSound("sound.caf");
		iOS.setBadge("1");

		Map<String, Object> extrasMap = new HashMap<>();
		extrasMap.put("params", extras);
		android.setExtras(extrasMap);
		iOS.setExtras(extrasMap);

		NotificationMessage.HMOS hmos = new NotificationMessage.HMOS();
		hmos.setAlert(msg);
		hmos.setTitle(title);
		hmos.setBadgeAddNumber(1);
		hmos.setCategory("IM");
		NotificationMessage.Android.Intent intent = new NotificationMessage.Android.Intent();
		intent.setUrl("action.system.home");
		hmos.setIntent(intent);

		NotificationMessage notificationMessage = new NotificationMessage();
		notificationMessage.setAlert(msg);
		notificationMessage.setAndroid(android);
		notificationMessage.setIos(iOS);
		notificationMessage.setHmos(hmos);
		param.setNotification(notificationMessage);

		// 目标人群
		Audience audience = new Audience();
		audience.setRegistrationIdList(regIds);
		// 指定目标
		param.setAudience(audience);

		// 或者发送所有人
		//param.setAudience(ApiConstants.Audience.ALL);

		// 指定平台
		param.setPlatform(Arrays.asList(Platform.android, Platform.ios));
		// 或者发送所有平台
		// param.setPlatform(ApiConstants.Platform.ALL);

		// Android厂商
		// param.setThirdNotificationMessage();

		// 短信补充
		// param.setSmsMessage();

		// 回调
		// param.setCallback();

		// options
		Options options = new Options();
		Map<String, Object> thirdPartyMap = new HashMap<>();
		Map<String, Object> huaweiMap = new HashMap<>();
		huaweiMap.put("distribution", "secondary_push");
		huaweiMap.put("importance", "NORMAL");
		huaweiMap.put("category", "IM");
		thirdPartyMap.put("huawei", huaweiMap);
		Map<String, Object> xiaomiMap = new HashMap<>();
		xiaomiMap.put("channel_id", "132913");
		thirdPartyMap.put("xiaomi", xiaomiMap);
		options.setClassification(1);
		options.setApnsProduction(true);
		options.setThirdPartyChannel(thirdPartyMap);

		param.setOptions(options);
		try {
			PushSendResult result = getPushApi().send(param);
			//System.out.println(result.toString());
		} catch (Exception e){
			//e.printStackTrace();
		}
	}

	private Sender mSender;

	/**
	 * 发送小米消息推送
	 */
	private void initXiaomi(List<String> regIds, String title, String msg, Map<String, String> extra){
		Constants.useOfficial();
		if (mSender == null) {
			mSender = new com.xiaomi.xmpush.server.Sender("hLvR2xBiwK/ekZNWUlS83g==");
		}
		if (extra == null) {
			extra = new HashMap<>();
		}
		extra.put(Constants.EXTRA_PARAM_NOTIFY_FOREGROUND, "0");
		extra.put("channel_id", "132913");
		extra.put("channel_name", "聊天通知");
		extra.put("channel_description", "聊天通知");
		extra.put(Constants.EXTRA_PARAM_SOUND_URI, "android.resource://com.wawwanxx.xxhui/raw/bell_p2p_msg_ntf.mp3");
		Message message = new Message.Builder()
				.title(title)
				.description(msg).payload(msg)
				.restrictedPackageName("com.wawwanxx.xxhui")
				.extra(extra)
				.notifyType(1)     // 使用默认提示音提示
				.build();
		try {
			Result result = mSender.send(message, regIds, 3);
			//log.debug("Server response: MessageId: " + result.getMessageId()
			//		+ " ErrorCode: " + JSON.toJSONString(result.getErrorCode()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 发送vivo消息推送 ok
	 * @param regId 注册序号
	 * @param title 标题
	 * @param msg 消息
	 */
	private void initVivo(String regId, String title, String msg, Map<String, String> extra) {
		try {
			if (extra == null) {
				extra = new HashMap<>();
			}
			com.vivo.push.sdk.notofication.Message message = new com.vivo.push.sdk.notofication.Message.Builder()
					//该测试手机设备订阅推送所得的regId，且已添加为测试设备
					.regId(regId).notifyType(1).title(title).content(msg).classification(1).timeToLive(1000)
					.skipType(1).networkType(-1).pushMode(0).clientCustomMap(extra)
					.requestId(String.valueOf(System.currentTimeMillis()))
					.build();
			com.vivo.push.sdk.notofication.Result resultMessage = getVivo().sendSingle(message);
			//log.debug("Server response: MessageId: " + resultMessage.toString());
		} catch (Exception e){
			e.printStackTrace();
		}
	}

	private com.vivo.push.sdk.server.Sender vivoSender;

	private com.vivo.push.sdk.server.Sender getVivo() throws Exception {
		if (vivoSender != null) {
			return vivoSender;
		}
		//注册登录开发平台网站获取到的appSecret
		vivoSender = new com.vivo.push.sdk.server.Sender("734e463b-800c-4f09-a17b-a6c4f62201fc");
		//注册登录开发平台网站获取到的appId和appKey
		com.vivo.push.sdk.notofication.Result result = vivoSender.getToken(105845697, "a51b023482fd73a4c7f4dc774c7cbb32");
		vivoSender.setAuthToken(result. getAuthToken());
		return vivoSender;
	}

	/**
	 * 发送vivo消息推送 ok
	 * @param regIds 注册序号
	 * @param title 标题
	 * @param msg 消息
	 */
	private void initVivo(List<String> regIds, String title, String msg, Map<String, String> extra) {
		try {
			if (extra == null) {
				extra = new HashMap<>();
			}

			com.vivo.push.sdk.notofication.Message message = new com.vivo.push.sdk.notofication.Message.Builder()
					//该测试手机设备订阅推送所得的regId，且已添加为测试设备
					.regId(regIds.get(0))
					.notifyType(1).title(title).content(msg).classification(1).timeToLive(1000)
					.skipType(1).networkType(-1).pushMode(0).clientCustomMap(extra)
					.requestId(String.valueOf(System.currentTimeMillis()))
					.build();
			com.vivo.push.sdk.notofication.Result result1 = getVivo().saveListPayLoad(message);
			if (result1.getResult() == 0) {
				Set<String> set = new HashSet<>(regIds.subList(1, regIds.size()));
				com.vivo.push.sdk.notofication.TargetMessage target = new com.vivo.push.sdk.notofication.TargetMessage.Builder()
						//该测试手机设备订阅推送所得的regId，且已添加为测试设备
						.regIds(set).taskId(result1.getTaskId()).build();
				com.vivo.push.sdk.notofication.Result resultMessage = getVivo().sendToList(target);
				//log.debug("Server response: MessageId: " + resultMessage.toString());
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	/**
	 * 发送oppo消息推送
	 * @param regId 注册序号
	 * @param title 标题
	 * @param msg 消息
	 */
	private void initOppo(String regId, String title, String msg){
		try {
			if (StrUtil.isEmpty(regId)) {
				return;
			}

			// 创建通知栏消息体
			Notification notification = getOppoNotification(title, msg);
			// 创建推送目标对象，传入注册ID
			Target target = Target.build(regId);
			// 调用单推接口，推送消息，获得调用结果
			com.oppo.push.server.Result result = getOppo().unicastNotification(notification, target);
			//System.out.println("msgId:"+result.getMessageId()+",token:"+result.getToken()+",reason:"+result.getReason());
		} catch (Exception e){
			e.printStackTrace();
		}
	}

	/**
	 * 发送oppo消息推送
	 * @param regId 注册序号
	 * @param title 标题
	 * @param msg 消息
	 */
	private void initOppo(List<String> regId, String title, String msg){
		try {
			// 创建通知栏消息体
			Notification notification = getOppoNotification(title, msg);
			// 创建推送目标对象，传入注册ID
			Map<Target, Notification> batch = new HashMap<>();
			for (String id : regId) {
				batch.put(Target.build(id), notification);
			}
			// 调用单推接口，推送消息，获得调用结果
			com.oppo.push.server.Result result = getOppo().unicastBatchNotification(batch);
			//System.out.println("msgId:"+result.getMessageId()+",token:"+result.getToken()+",reason:"+result.getReason());
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	public com.oppo.push.server.Sender oppoSender;

	private com.oppo.push.server.Sender getOppo() throws Exception {
		if (oppoSender != null) {
			return oppoSender;
		}
		oppoSender = com.oppo.push.server.Sender.newBuilder()
				.appKey("5849fbf9b56040818b5c868512da25e4") // 设置appKey
				.masterSecret("01ec46a101324e58bca9db97f49c8f6a") // 设置masterSecret
				.env(Environment.CHINA_PRODUCTION)  // 中国
				.httpMaxConnection(64) // 设置http最大连接数
				.httpMaxRoute(64)   // 设置最大http路由连接数
				.httpConnectionTimeout(5000) // http连接超时时间
				.httpConnectRequestTimeout(5000) // 等待连接超时时间
				.httpSocketTimeout(5000) // socket超时时间
				.build();
		return oppoSender;
	}

	/**
	 * 获取oppo通知
	 * @param title 标题
	 * @param msg 消息
	 * @return
	 */
	private Notification getOppoNotification(String title, String msg){
		Notification notification = new Notification();
		notification.setTitle(title);
		notification.setContent(msg);
		notification.setStyle(1);
		notification.setBadgeMessageCount(1);
		notification.setAppMessageId(UUID.randomUUID().toString());
		notification.setClickActionType(0);
		notification.setShowTimeType(0);
		notification.setNetworkType(0);
		return notification;
	}

	public static void main(String[] args) {
//		List<String> ids = new ArrayList<>();
//		ids.add("160a3797c93c9682d7e");
//		PushSendParam param = initPushReg(ids,"测试消息2",new HashMap<>(),"测试2");
//		PushApi pushApi = new PushApi.Builder()
//				.setAppKey("6a59cc712167aa5917deecf7")
//				.setMasterSecret("0a3ffb228f37895807cdfa6d")
//				.build();
//		PushSendResult result = pushApi.send(param);
//		System.out.println(result);
		List<String> ids = new ArrayList<>();
		HashMap<String, String> map = new HashMap<>();
		map.put("type", "call");
		map.put("data", "{'call':'你好'}");
		//handlerPush("oppo", "OPPO_CN_223a2226597368ee6d600e5cf3d7dfbc", "", "这是一个华为消息7","通知到了", null);
		//handlerPush("vivo", "v2-CRmxgWGIrLs_qHql_EeUtTC_QqmR3kiQLCEgCdiLIu2kjbc_EZH2ihxL", "", "测试账号", "不是消息", map);
		//handlerPush("xiaomi", "wofBRH5Zf9/Em36j+wL0Yv+GXpp9I2F1hY3tCb9R9Yepa3t8mqqYll8Xc/ppyuYd", "", "这是一个小米消息","通知到了小米", null);
		//handlerPush("huawei", "ALPyHE1_6IzEVkEzu7zqSLQ5ULWGVwmTJfrHVxMcff6DtektBR8sqWcdC79WCei8JgdMj0jk9_DWvw4a-thT60LNNPB15XMwcKO_CUACEdeYQ2mlvX-vS1iEoLEPRzLrYw", "", "这是一个华为消息","通知到了华为", null);
		//handlerPush("honor", "s18069ps301291893q1ssro2o40s1630-n262n542r9669q62o83s390306179rro-775875632-654-6105326555582-PA-0052993947080949113-5", "", "这是一个vivo消息","通知到了vivo", null);
		//handlerPush("", "", "141fe1da9f935279db5", "文本消息1","通话1", map);
	}
}
