package com.palmnest.service.wechat.impl;

import com.palmnest.application.Constants;
import com.palmnest.application.bean.InMessage;
import com.palmnest.application.bean.NewsOutMessage;
import com.palmnest.application.bean.OutMessage;
import com.palmnest.application.core.util.LogExceptionStackUtil;
import com.palmnest.dao.estateserve.*;
import com.palmnest.model.estateserve.*;
import com.palmnest.service.AsynchronousDataService;
import com.palmnest.service.Executable;
import com.palmnest.service.wechat.EventMsgManager;
import com.palmnest.service.wechat.MessageProcessingManager;
import com.palmnest.service.wechat.ReplayContentManager;
import com.palmnest.service.wechat.WeChatApiManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 微信消息接收统一处理
 *
 * @author yubing
 * @date 2014-04-10
 */
@Slf4j
@Component("messageProcessingManager")
public class MessageProcessingManagerImpl implements MessageProcessingManager {


	@Autowired
	private ReplayContentManager    replayContentManager;
	@Autowired
	private WeChatApiManager        WeChatApiManager;
	@Autowired
	private EventMsgManager         eventMsgManager;
	// 线程异步处理数据Serveice
	@Autowired
	private AsynchronousDataService asynchronousDataService;
	@Autowired
	private ScReceiverecordDao      scReceiverecordDao;
	@Autowired
	private ReceiveTextDao          receiveTextDao;
	@Autowired
	private ScReceivelocationDao    scReceivelocationDao;
	@Autowired
	private ReceivePicDao           receivePicDao;
	@Autowired
	private ScReceivevedioDao       scReceivevedioDao;
	@Autowired
	private ScReceivevoiceDao       scReceivevoiceDao;
	@Autowired
	private ScReceiveurlDao         scReceiveurlDao;

	private OutMessage outMessage;

	public void setOutMessage(OutMessage outMessage) {
		this.outMessage = outMessage;
	}

	public OutMessage getOutMessage() {
		return outMessage;
	}

	public void allType(InMessage msg) {
		/*TextOutMessage out = new TextOutMessage();
		out.setContent("亲，已收到！欢迎继续告诉我现场情况。");
		setOutMessage(out);*/
	}

	// TODO文本
	public void textTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg, Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 文本
		final WxReceivetext receive = new WxReceivetext();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setText(msg.getContent());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceivetext new_receive = receiveTextDao.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getId());
				scReceiverecordDao.save(record); // 保存文本消息
				return null;
			}
		});
		afterProcess(msg, outMessage);
	}

	// TODO地理位置信息
	public void locationTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg,
				Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 地理位置
		final WxReceivelocation receive = new WxReceivelocation();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setLocationX(msg.getLocation_X());
		receive.setLocationY(msg.getLocation_Y());
		receive.setLabel(msg.getLabel());
		receive.setScale(msg.getScale());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceivelocation new_receive = scReceivelocationDao
						.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getId());
				scReceiverecordDao.save(record);
				return null;
			}
		});
		afterProcess(msg, outMessage);
	}

	// TODO图片
	public void imageTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg,
				Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 图片
		final WxReceivepic receive = new WxReceivepic();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setMediaId(msg.getMediaId());
		receive.setPicUrl(msg.getPicUrl());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceivepic new_receive = receivePicDao.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getId());
				scReceiverecordDao.save(record);
				return null;
			}
		});
		afterProcess(msg, outMessage);
	}

	// TODO视频
	public void videoTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg,
				Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 视频
		final WxReceivevedio receive = new WxReceivevedio();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setMediaId(msg.getMediaId());
		receive.setThumbMediaId(msg.getThumbMediaId());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceivevedio new_receive = scReceivevedioDao.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getId());
				scReceiverecordDao.save(record);
				return null;
			}
		});

		afterProcess(msg, outMessage);
	}

	// TODO语音
	public void voiceTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg,
				Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 语音
		final WxReceivevoice receive = new WxReceivevoice();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setMediaId(msg.getMediaId());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setFormat(msg.getFormat());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceivevoice new_receive = scReceivevoiceDao.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getReceiveVoiceId());
				scReceiverecordDao.save(record);

				return null;
			}
		});
		afterProcess(msg, outMessage);
	}

	// TODO链接
	public void linkTypeMsg(InMessage msg) {
		// 用户消息记录
		final WxReceiverecord record = getScReceiverecord(msg,
				Constants.InFo_TYPE_NORMAL);
		record.setMsgType(msg.getMsgType());
		// 链接
		final WxReceiveurl receive = new WxReceiveurl();
		receive.setDevelopId(msg.getToUserName());
		receive.setOpenId(msg.getFromUserName());
		receive.setUrl(msg.getUrl());
		receive.setDescription(msg.getDescription());
		receive.setMsgId(msg.getMsgId().intValue());
		receive.setCreateTime(new Date());

		asynchronousDataService.store(new Executable() {
			@Override
			public Void execute() {
				WxReceiveurl new_receive = scReceiveurlDao.save(receive); // 保存用户消息记录
				record.setMsgId(new_receive.getId());
				scReceiverecordDao.save(record);

				return null;
			}
		});
		afterProcess(msg, outMessage);
	}

	// TOD事件
	public void eventTypeMsg(InMessage msg) {
		try {
			Method method = eventMsgManager.getClass().getMethod(msg.getEvent(), InMessage.class);
			if (method != null) {
				Object obj = method.invoke(eventMsgManager, msg);
				if (obj != null) {
					setOutMessage((OutMessage) obj);
				} else {
					setOutMessage(null);
				}
			}
		} catch (SecurityException e) {
			e.printStackTrace();
			log.error("eventTypeMsg occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (NoSuchMethodException e) {
			log.error("eventTypeMsg occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (IllegalArgumentException e) {
			log.error("eventTypeMsg occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (IllegalAccessException e) {
			log.error("eventTypeMsg occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		} catch (InvocationTargetException e) {
			log.error("eventTypeMsg occur error." + LogExceptionStackUtil.LogExceptionStack(e));
		}
	}

	@Override
	public boolean beforeProcess(InMessage inMessage) {

		return false;
	}

	/*
	 * 接收消息处理完成之后给相应提示，调用关键字查询接口封装返回数据 (non-Javadoc)
	 * @see
	 * com.palmnest.service.wechat.MessageProcessingManager#afterProcess(com
	 * .palmnest.bean.InMessage, com.palmnest.bean.OutMessage)
	 */
	public void afterProcess(InMessage inMessage, OutMessage outMessage) {
		String keywordName = "default";
		if (StringUtils.isNotBlank(inMessage.getContent())) {
			keywordName = inMessage.getContent();

			//适配 #关键字#，比如#建议#
			int index = keywordName.lastIndexOf("#");
			if (index != -1) {
				keywordName = keywordName.substring(0, index + 1);
			}
		}
		outMessage = replayContentManager.queryReplayContent(keywordName, inMessage.getToUserName());
		setOutMessage(outMessage);
	}

	/**
	 * 事件处理，返回处理消息
	 *
	 * @param msg
	 * @return
	 */
	public OutMessage getEventReplayConent(InMessage msg) {
		OutMessage objOut = replayContentManager.queryReplayContent(
				msg.getEvent(), msg.getToUserName());
		if (objOut instanceof NewsOutMessage) {
			NewsOutMessage out = (NewsOutMessage) objOut;
			for (int i = 0; i < out.getArticles().size(); i++) {
				String url = out.getArticles().get(i).getUrl();
				if (url.contains("?")) {
					url = url + "&openId=" + msg.getFromUserName()
							+ "&developId=" + msg.getToUserName();
				} else {
					url = url + "?openId=" + msg.getFromUserName()
							+ "&developId=" + msg.getToUserName();
				}
				out.getArticles().get(i).setUrl(url);
			}
			return out;
		} else {
			return objOut;
		}
	}

	public WxReceiverecord getScReceiverecord(InMessage msg, String infoType) {
		// 保存用户消息接收记录信息
		WxReceiverecord record = new WxReceiverecord();
		record.setDevelopId(msg.getToUserName());
		record.setOpenId(msg.getFromUserName());
		record.setInfoType(infoType);
		record.setCreateTime(new Date());
		return record;
	}

}
