package com.railway.business.push.service.impl;

import com.gexin.fastjson.JSONObject;
import com.gexin.rp.sdk.base.IBatch;
import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.SingleMessage;
import com.gexin.rp.sdk.base.impl.Target;
import com.gexin.rp.sdk.exceptions.RequestException;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.template.AbstractTemplate;
import com.gexin.rp.sdk.template.NotificationTemplate;
import com.gexin.rp.sdk.template.TransmissionTemplate;
import com.gexin.rp.sdk.template.style.Style0;
import com.railway.business.push.domain.BusPushMsg;
import com.railway.business.push.enums.PushEnum;
import com.railway.business.push.mapper.BusPushMsgMapper;
import com.railway.business.push.service.IBusPushMsgService;
import com.railway.common.utils.SecurityUtils;
import com.railway.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.Date;
import java.util.List;
/**
* 个推消息表
* @author author
* @date 2021/11/16
*/
@Slf4j
@Service
@Transactional(readOnly = true)
public class BusPushMsgServiceImpl implements IBusPushMsgService{

	private final ISysConfigService configService;
	private BusPushMsgMapper busPushMsgMapper;

	/**
	 * 每个应用都对应一个唯一的AppID
	 */
	private String appId;
	/**
	 * SDK 与服务器端通过 Appkey 互相识别
	 */
	private  String appKey;
	/**
	 * 服务端API鉴权码
	 */
	private String masterSecret;

	/**
	 * 批量单传使用
	 */
	private IGtPush push;

	public BusPushMsgServiceImpl(ISysConfigService configService, BusPushMsgMapper busPushMsgMapper) {
		this.configService = configService;
		this.busPushMsgMapper = busPushMsgMapper;
		this.appId = this.configService.selectConfigByKey("getui.appId");
		this.appKey = this.configService.selectConfigByKey("getui.appKey");
		this.masterSecret = this.configService.selectConfigByKey("getui.masterSecret");

		push = new IGtPush(appKey, masterSecret);
	}

	/**
	* 新增
	*/
	@Transactional(rollbackFor = Exception.class)
	public int create(BusPushMsg busPushMsg) {
	    busPushMsg.setCreateTime(new Date());
        busPushMsg.setCreateBy(SecurityUtils.getUsername());
		busPushMsg.setPushStatus("0");
		busPushMsg.setPushLoop(0);
		return busPushMsgMapper.insert(busPushMsg);
	}

	/**
	* 删除
	*/
	@Transactional(rollbackFor = Exception.class)
	public int delete(String[] ids) {
		int r =0;
		for (String id : ids) {
			int j= busPushMsgMapper.delete(id);
			r = r + j;
		}
		return	r;
	}

	/**
	* 更新
	*/
	@Transactional(rollbackFor = Exception.class)
	public int update(BusPushMsg busPushMsg) {
		busPushMsg.setUpdateTime(new Date());
    	busPushMsg.setUpdateBy(SecurityUtils.getUsername());
		return busPushMsgMapper.update(busPushMsg);
	}

	/**
	* 获取单个
	*/
	public BusPushMsg getInfo(String id) {
		return busPushMsgMapper.getInfo(id);
	}

	/**
	* 查询列表
	*/
	public List<BusPushMsg> getList(BusPushMsg busPushMsg) {
		return busPushMsgMapper.getList(busPushMsg);
	}

	@Override
	public List<BusPushMsg> selectAppMsg() {
		return busPushMsgMapper.selectAppMsg();
	}

	@Override
	public List<BusPushMsg> getListTop5(BusPushMsg busPushMsg) {
		// 查询已推送的
		busPushMsg.setPushStatus(PushEnum.PUSH_STATUS_SUCCES.getCode());
		return busPushMsgMapper.getListTop5(busPushMsg);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateBatch(List<BusPushMsg> msgPos) {
		for (BusPushMsg msg : msgPos) {
			busPushMsgMapper.update(msg);
		}
	}

	/**
	 * 对单个用户推送消息
	 *
	 * @return
	 */
	@Override
	public String pushToSingle(BusPushMsg msgPo) {
		AbstractTemplate template = getTransmissionTemplate(msgPo.getContent());
		// 单推消息类型
		SingleMessage message = getSingleMessage(template);
		Target target = new Target();
		target.setAppId(appId);
		target.setClientId(msgPo.getClientId());
		IPushResult ret = null;
		try {
			if (push != null) {
				ret = push.pushMessageToSingle(message, target);
			}
			else {
				return "个推服务IGtPush创建异常";
			}
		} catch (RequestException e) {
			log.error("消息发送失败,尝试1次重发", e);
			ret = push.pushMessageToSingle(message, target, e.getRequestId());
		}
		if (ret != null) {
			JSONObject jsonObject = new JSONObject();
			jsonObject.putAll(ret.getResponse());
			return jsonObject.toJSONString();
		} else {
			return "服务器响应异常";
		}
	}

	/**
	 * 透传消息,消息传递到客户端只有消息内容，展现形式由客户端自行定义
	 * 注：ios端只支持透传消息
	 *
	 * @param content
	 * @return
	 */
	private TransmissionTemplate getTransmissionTemplate(String content) {
		TransmissionTemplate template = new TransmissionTemplate();
		template.setAppId(appId);
		template.setAppkey(appKey);
		//透传消息设置，1为强制启动应用，客户端接收到消息后就会立即启动应用；2为等待应用启动
		template.setTransmissionType(1);
		template.setTransmissionContent(content);
		return template;
	}

	/**
	 * 通知模板
	 * @param title
	 * @param text
	 * @return
	 */
	private NotificationTemplate getNotificationTemplate(String title, String text) {
		Style0 style = new Style0();
		// 设置推送标题、推送内容
		style.setTitle(title);
		style.setText(text);
		// style.setLogo("push.png");  // 设置推送图标
		// 设置响铃、震动等推送效果
		style.setRing(true);  // 设置响铃
		style.setVibrate(true);  // 设置震动

		// 选择通知模板
		NotificationTemplate template = new NotificationTemplate();
		template.setAppId(appId);
		template.setAppkey(appKey);
		template.setStyle(style);
		return template;
	}

	private SingleMessage getSingleMessage(AbstractTemplate template) {
		SingleMessage message = new SingleMessage();
		message.setData(template);
		// 设置消息离线，并设置离线时间
		message.setOffline(true);
		// 离线有效时间，单位为毫秒
		message.setOfflineExpireTime(72 * 3600 * 1000);
		message.setPriority(1);
		// 判断客户端是否wifi环境下推送。1为仅在wifi环境下推送，0为不限制网络环境，默认不限
		message.setPushNetWorkType(0);
		return message;
	}

	/**
	 * 批量单推
	 * <p>
	 * 当单推任务较多时，推荐使用该接口，可以减少与服务端的交互次数。
	 */
	@Override
	public void pushToSingleBatch(List<BusPushMsg> msgPos) {
		IBatch batch = push.getBatch();
		IPushResult ret = null;
		try {
			//构建客户a的透传消息a
			for (BusPushMsg msgPo : msgPos) {
				constructClientTransMsg(msgPo.getClientId(), batch, msgPo.getContent());
			}
			ret = batch.submit();
		} catch (Exception e) {
			e.printStackTrace();
			try {
				ret = batch.retry();
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		if (ret != null) {
			log.info(ret.getResponse().toString());
		} else {
			log.info("服务器响应异常");
		}
	}

	private void constructClientTransMsg(String cid, IBatch batch, String content) throws Exception {
		AbstractTemplate template = getTransmissionTemplate(content);
		SingleMessage message = getSingleMessage(template);
		// 设置推送目标，填入appid和clientId
		Target target = new Target();
		target.setAppId(appId);
		target.setClientId(cid);
		batch.add(message, target);
	}

	/**

	 public BusPushMsgServiceImpl() {

	 }

	 public BusPushMsgServiceImpl(String appId, String appKey, String masterSecret, boolean enable) {
		 this.appId = appId;
		 this.appKey = appKey;
		 this.masterSecret = masterSecret;
		 this.enable = enable;
		 push = new IGtPush(appKey, masterSecret);
	 }

	public static void main(String[] args) {
		BusPushMsgServiceImpl push = new BusPushMsgServiceImpl("Y3xRJmer116Bb1HhqnZav7","N2oftDIHyC9o1Ue73Cx3fA","OZhDEZbGTZ9tc8P8IQ3Mk3",true);
		BusPushMsg msgPo = new BusPushMsg();
		msgPo.setClientId("d2a737569978aa43f42b2a8c562f69b1");
		msgPo.setContent("测试服务器端push内容main");
		String result = push.pushToSingle(msgPo);
		System.out.println(result);
	}
	 */

}
