package com.ssj.service.weixin.push.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ssj.bean.weixin.push.domain.PushTemplate;
import com.ssj.bean.weixin.push.domain.SendTemplateShort;
import com.ssj.bean.weixin.push.domain.TbWxTemplate;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.rabbitmq.TopicRabbitConfig;
import com.ssj.framework.core.rabbitmq.producer.BaseRabbitSend;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.weixin.util.NewsUtil;
import com.ssj.service.weixin.push.service.PushTemplateService;
import com.ssj.service.weixin.push.service.dao.PushTemplateDao;
import com.ssj.taskthread.Task;
import com.ssj.taskthread.ThreadPool;
import com.ssj.util.WxTemplateCacheUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Calendar;
import java.util.Date;
import java.util.List;


/** 
 * @author  wuwen 
 * @version 2019年4月17日18:11:28
 * 类说明 
 */

@Service
@Transactional
public class PushTemplateServiceImpl  extends BaseServiceImpl<PushTemplate, String> implements PushTemplateService {
	
	private static Logger logger = LoggerFactory.getLogger(PushTemplateServiceImpl.class);
	
    @Autowired
	private PushTemplateDao dao;
	@Autowired
	private TokenManager tokenManager;
 
	@Override
	public boolean savePushWxTemplate(SendTemplateShort sendTemplateShort) {
		boolean is=true;
		ThreadPool.getInstance().addTask(new SyncSaveAndSendPushDBTask(sendTemplateShort,dao));
		return is;
	}

	@Override
	public void saveAndSendPushWxTemplate(SendTemplateShort sendTemplateShort) {
		ThreadPool.getInstance().addTask(new SyncSaveAndSendPushDBTask(sendTemplateShort,dao));
	}

	public boolean savePushWxTemplateByDb(SendTemplateShort sendTemplateShort) {
		logger.info("直接保存推送信息data:"+JSONObject.toJSONString(sendTemplateShort));
		try {
			PushTemplate pushTemplate =new PushTemplate();
			pushTemplate.setClickUrl(sendTemplateShort.getUrl());
			pushTemplate.setInterVal(sendTemplateShort.getInterVal());
			pushTemplate.setOpenid(sendTemplateShort.getTouser());
			pushTemplate.setTopColor(sendTemplateShort.getTopColor());
			pushTemplate.setTotal(sendTemplateShort.getTotal());
			pushTemplate.setWxTplSid(sendTemplateShort.getTemplate_id_short());
			pushTemplate.setContent(JSONObject.toJSONString(sendTemplateShort.getData()));
			if(sendTemplateShort.getMiniprogram()!=null && StringUtils.isNotEmpty(sendTemplateShort.getMiniprogram().getAppid())){
				pushTemplate.setMiniprogram(JSONObject.toJSONString(sendTemplateShort.getMiniprogram()));
			}
			pushTemplate.setCreateTime(new Date());
			pushTemplate.setCurTotal(0);
			pushTemplate.setIsSuccess(0);
			pushTemplate.setStat(1);
			pushTemplate.setTryTime(0);
			pushTemplate.setRemark("");
			pushTemplate=this.save(pushTemplate);
			sendTemplateShort.setPushTemplateId(pushTemplate.getId());
		} catch (Exception e) {
			logger.error("保存推送信息异常...");
			return false;
		}
		return true;
	}
	
	
	

	@Override
	public void pushTemplate() {
		List<PushTemplate> list =dao.getPushTemplateStat();
		if(list !=null && list.size()>0){
			for (PushTemplate pushTemplate : list) {
				NewsUtil.sendTemplate( tokenManager.getSSJAccessToken(), pushTemplate.getContent());
				if(pushTemplate.getTotal() == 2){
					this.delete(pushTemplate);
				}else{
					pushTemplate.setTotal(pushTemplate.getTotal()+1);
					this.save(pushTemplate);
				}
			}
		}
	}

	@Override
	public void savePushTemplate(String objectId, String content) {
		PushTemplate pushTemplate = new PushTemplate();
		pushTemplate.setContent(content);
		pushTemplate.setCreateTime(new Date());
		//pushTemplate.setObjectId(objectId);
		pushTemplate.setStat(1);
		pushTemplate.setTotal(0);
		this.save(pushTemplate);
	}

	@Override
	public void pushWxTemplate() {
		List<PushTemplate> TempList =dao.getPushWxTemplateStat();
		logger.info("定时微信推送任务开始，推送任务量为："+TempList.size());
		int errorNum=0;
		for (PushTemplate pushTemplate : TempList) {
			try{
				//需要重复推送，数据库查出来的cur_total<total，
				if(pushTemplate.getTotal()>0 && pushTemplate.getSuccessTime()!=null){
					Calendar lastTime=Calendar.getInstance();
					lastTime.setTime(pushTemplate.getSuccessTime());

					Calendar curTime=Calendar.getInstance();
					curTime.setTime(new Date());

					long time=curTime.getTimeInMillis()-lastTime.getTimeInMillis();
					long minute=(time)/(1000*60);//转化minute

					if(minute<pushTemplate.getInterVal()){//没到时间，下一条
						continue;
					}
				}
				if(StringUtils.isEmpty(pushTemplate.getWxTplSid())){
					pushTemplate.setRemark("WxTplSid为空，请注意检查来源代码逻辑...");
					pushTemplate.setTryTime(7);
					errorNum=errorNum+1;
				}else if(StringUtils.isEmpty(pushTemplate.getOpenid())){
					pushTemplate.setRemark("OPENID为空，请注意检查来源代码逻辑...");
					pushTemplate.setTryTime(7);
					errorNum=errorNum+1;
				}else {
					TbWxTemplate tbWxTemplate= WxTemplateCacheUtils.getTbWxTemplate(pushTemplate.getWxTplSid(),null,null);
					if(tbWxTemplate==null || StringUtils.isEmpty(tbWxTemplate.getTemplateId())){
						pushTemplate.setRemark("模板池无法得到微信模板ID...");
						pushTemplate.setTryTime(pushTemplate.getTryTime()+1);
						errorNum=errorNum+1;
					}else{
						String msg= NewsUtil.WX_TPL_BODY
								.replace(NewsUtil.TPL_CODE_OPENID, pushTemplate.getOpenid())
								.replace(NewsUtil.TPL_CODE_TPLID, tbWxTemplate.getTemplateId())
								.replace(NewsUtil.TPL_CODE_URL, StringUtils.isNotEmpty(pushTemplate.getClickUrl())?pushTemplate.getClickUrl():"")
								.replace(NewsUtil.TPL_CODE_DATA, pushTemplate.getContent())
								.replace(NewsUtil.TPL_CODE_TOPCOLOR, StringUtils.isNotEmpty(pushTemplate.getTopColor())?pushTemplate.getTopColor():"");
						if(StringUtils.isNotEmpty(pushTemplate.getMiniprogram())){
							msg=msg.replace(NewsUtil.TPL_CODE_MINIPROQRAM_TEXT, NewsUtil.TPL_SUB_MINIPROQRAM_DATA);
							msg=msg.replace(NewsUtil.MINIPROQRAM_DATA, pushTemplate.getMiniprogram());
						}else{
							msg=msg.replace(NewsUtil.TPL_CODE_MINIPROQRAM_TEXT, "");
						}
						//再去查询，防止重复推送,定时推送数据锁定一分钟
						if(StringUtils.isNotEmpty(pushTemplate.getId())){
							pushTemplate=this.getById(pushTemplate.getId());
						}
						if(pushTemplate.getIsSuccess()==0){
							JSONObject result = NewsUtil.sendTemplate(tokenManager.getSSJAccessToken(), msg);
							if(result != null && "0".equals(result.getString("errcode"))){
								pushTemplate.setIsSuccess(1);
								pushTemplate.setSuccessTime(new Date());
								pushTemplate.setCurTotal(pushTemplate.getCurTotal()+1);
								pushTemplate.setRemark("");
							}else{
								pushTemplate.setTryTime(pushTemplate.getTryTime()+1);
								pushTemplate.setRemark("errcode:"+result.getString("errcode"));
								errorNum=errorNum+1;
							}
						}
					}
				}
				this.save(pushTemplate);
			}catch(Exception e){
				e.printStackTrace();
				logger.error(pushTemplate.getWxTplSid()+"3分钟微信推送任务结束，推送异常...");
			}
		}
		logger.info("定时微信推送任务结束，推送任务量为："+TempList.size()+",\t成功量："+(TempList.size()-errorNum)+",\t失败量："+errorNum);
	}

	@Override
	public PagingAndSortingRepository<PushTemplate, String> getDao() {
		return dao;
	}
	
	

}


class SyncSaveAndSendPushDBTask extends Task{
	
	private static Logger logger = LoggerFactory.getLogger(SyncSaveAndSendPushDBTask.class);
	
	private SendTemplateShort sendTemplateShort;
	
	private PushTemplateDao dao;
	
	public SyncSaveAndSendPushDBTask(SendTemplateShort sendTemplateShort,PushTemplateDao dao) {
	    super();
	    this.sendTemplateShort=sendTemplateShort;
	    this.dao=dao;
	} 
	
	@Override
	public void run() {
		try {
			savePushWxTemplateByDb(sendTemplateShort);
		} catch (Exception e) {
			logger.error("推送信息保存异常...");
		}
		try {
			String uuid=BaseRabbitSend.convertAndTopicSend(
					TopicRabbitConfig.exchange_task,
					TopicRabbitConfig.topic_push_messages_wx, 
					sendTemplateShort);
			logger.error("已加入推送信息队列数据uuid："+uuid+" data:"+JSONObject.toJSONString(sendTemplateShort));
		} catch (Exception e) {
			logger.error("推送信息队列异常...");
		}
	}

	public boolean savePushWxTemplateByDb(SendTemplateShort sendTemplateShort) {
		logger.info("直接保存推送信息data:"+JSONObject.toJSONString(sendTemplateShort));
		try {
			PushTemplate pushTemplate =new PushTemplate();
			pushTemplate.setClickUrl(sendTemplateShort.getUrl());
			pushTemplate.setInterVal(sendTemplateShort.getInterVal());
			pushTemplate.setOpenid(sendTemplateShort.getTouser());
			pushTemplate.setTopColor(sendTemplateShort.getTopColor());
			pushTemplate.setTotal(sendTemplateShort.getTotal());
			pushTemplate.setWxTplSid(sendTemplateShort.getTemplate_id_short());
			pushTemplate.setContent(JSONObject.toJSONString(sendTemplateShort.getData()));
			if(sendTemplateShort.getMiniprogram()!=null && StringUtils.isNotEmpty(sendTemplateShort.getMiniprogram().getAppid())){
				pushTemplate.setMiniprogram(JSONObject.toJSONString(sendTemplateShort.getMiniprogram()));
			}
			pushTemplate.setCreateTime(new Date());
			pushTemplate.setCurTotal(0);
			pushTemplate.setIsSuccess(0);
			pushTemplate.setStat(1);
			pushTemplate.setTryTime(0);
			pushTemplate.setRemark("");
			pushTemplate=dao.save(pushTemplate);
			sendTemplateShort.setPushTemplateId(pushTemplate.getId());
		} catch (Exception e) {
			logger.error("保存推送信息异常...");
			return false;
		}
		return true;
	}
	
	
	
}



