package cn.hmsoft.weixin.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.constants.FrameStatus;
import cn.hmsoft.frame.data.model.FrameModule;
import cn.hmsoft.frame.module.FrameModuleConfig;
import cn.hmsoft.helper.BeanHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.log.LogHelper;
import cn.hmsoft.weixin.data.dao.WxDefineDao;
import cn.hmsoft.weixin.data.dao.WxMsgProcessorDao;
import cn.hmsoft.weixin.data.dao.WxMsgReplyDao;
import cn.hmsoft.weixin.data.dao.WxParamDao;
import cn.hmsoft.weixin.data.dao.WxTemplateDao;
import cn.hmsoft.weixin.data.model.WxApiErr;
import cn.hmsoft.weixin.data.model.WxDefine;
import cn.hmsoft.weixin.data.model.WxMsgProcessor;
import cn.hmsoft.weixin.data.model.WxMsgReply;
import cn.hmsoft.weixin.data.model.WxParam;
import cn.hmsoft.weixin.data.model.WxTemplate;
import cn.hmsoft.weixin.data.model.WxUser;
import cn.hmsoft.weixin.data.model.WxUserLog;
import cn.hmsoft.weixin.request.TokenRequestThread;

public class WeiXinModuleConfig extends FrameModuleConfig {

	@Override
	public String setModule_name() {
		return WeiXinParamUtil.ModuleName;
	}

	@Override
	public String setModule_version() {
		return WeiXinParamUtil.ModuleVersion;
	}

	@Override
	public boolean restart() throws Exception {
		this.stop();
		Thread.sleep(5000);
		return this.start();
	}

	@Override
	protected boolean start() throws Exception {
		if (!loadWeiXin()) {
			WeiXinUtil.WeiXinDefineMap = null;
			return false;
		}
		WeiXinParamUtil.WeiXinModuleConfig = this;
		// 加载后台线程
		return true;

	}

	@Override
	protected boolean stop() throws Exception {
		// 停止所有线程
		for (WxDefine wx : WeiXinUtil.WeiXinDefineMap.values()) {
			if (wx.getTokenThread() != null) {
				try {
					wx.getTokenThread().interrupt();
				} catch (Exception e) {

				}
			}
		}
		return true;
	}

	private static boolean reloadWeiXin() {
		try {
			WeiXinUtil.WeiXinDefineMap = new LinkedHashMap<String, WxDefine>();
			WeiXinUtil.WeiXinDefineArray = new ArrayList<WxDefine>();
			List<WxDefine> list = SpringHelper.getBean(WxDefineDao.class).listWeiXin(FrameStatus.Active.toString());
			for (WxDefine wx : list) {
				if (FrameStatus.Active.toString().equals(wx.getApp_status())) {
					WeiXinUtil.WeiXinDefineMap.put(wx.getApp_id(), wx);
					WeiXinUtil.WeiXinDefineArray.add(wx);
				}
			}
			if (WeiXinUtil.WeiXinDefineMap.keySet().size() == 0) {
				return false;
			}
			Map<String, String> paramMap = new HashMap<String, String>();
			for (WxParam param : SpringHelper.getBean(WxParamDao.class).list("wx_id", 0))
				paramMap.put(param.getParam_name(), param.getParam_value());
			BeanHelper.setStaticFields(WeiXinParamUtil.class, paramMap);

			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	private boolean loadWeiXin() {
		// 加载微信配置
		if (!reloadWeiXin()) {
			LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：没有配置可用的任何公众号，表[WX_DEFINE]");
			return false;
		}

		// 判断user表是否存在
		try {
			SpringHelper.AppGobalDao.find(WxUser.class, 0);
		} catch (Exception e) {
			LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：未找到微信所需用户表[WX_USER]");
			return false;
		}
		// 判断Log表是否存在
		try {
			SpringHelper.AppGobalDao.find(WxUserLog.class, 0);
		} catch (Exception e) {
			LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：未找到微信所需用户记录表[WX_USER_LOG]");
			return false;
		}
		// 加载错误常量
		try {
			for (WxApiErr err : SpringHelper.AppGobalDao.all(WxApiErr.class))
				WeiXinUtil.ApiErrorMap.put(err.getErr_code(), err.getErr_msg());
		} catch (Exception e) {
			LogHelper.error(e);

		}
		// 加载模版消息
		try {

		} catch (Exception e) {

		}
		// 加载消息处理器
		loadWeiXinConfig(module, null);
		return true;
	}

	/*******************************
	 * 加载微信其他数据
	 */
	public static void loadWeiXinConfig(FrameModule module, Integer wx_id) {
		for (WxDefine wx : WeiXinUtil.WeiXinDefineMap.values()) {
			if (wx_id != null && wx.getWx_id() - wx_id != 0)
				continue;
			// 线程锁定，防止冲突
			synchronized (WeiXinUtil.WeiXinDefineMap) {

				Map<String, String> replyMap = new LinkedHashMap<String, String>();
				Map<String, WxMsgProcessor> processorMap = new LinkedHashMap<String, WxMsgProcessor>();
				Map<String, List<WxTemplate>> templateMap = new LinkedHashMap<String, List<WxTemplate>>();
				Map<String, String> paramMap = new LinkedHashMap<String, String>();

				try {
					for (WxMsgProcessor processor : SpringHelper.getBean(WxMsgProcessorDao.class)
							.listMsgProcessor(wx.getWx_id()))
						processorMap.put(processor.getMsg_type(), processor);
				} catch (Exception e) {
					LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：未找到微信消息处理器表[WX_MSG_PROCESSOR]");
				}
				try {
					for (WxMsgReply msg : SpringHelper.getBean(WxMsgReplyDao.class).listMsgReply(wx.getWx_id())) {
						if (msg.getMsg_name() == null || msg.getMsg_content() == null)
							continue;
						for (String s : msg.getMsg_name().split(",")) {
							if (replyMap.containsKey(s))
								replyMap.put(s, wx.getMsgReplyMap().get(s) + "\n" + msg.getMsg_content());
							else
								replyMap.put(s, msg.getMsg_content());
						}
					}
				} catch (Exception e) {
					LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：未找到微信文本消息自动回复表[WX_MSG_REPLY]");
				}

				try {
					for (WxParam msg : SpringHelper.getBean(WxParamDao.class).list("wx_id", wx.getWx_id())) {
						paramMap.put(msg.getParam_name(), msg.getParam_value());
					}
				} catch (Exception e) {
				}

				try {
					for (WxTemplate template : SpringHelper.getBean(WxTemplateDao.class).listTemplate(wx.getWx_id())) {
						if (!FrameStatus.Active.toString().equals(template.getTemplate_status())
								|| StringHelper.isEmpty(template.getBusiness_type())
								|| StringHelper.isEmpty(template.getTemplate_code()))
							continue;
						if (!templateMap.containsKey(template.getBusiness_type()))
							templateMap.put(template.getBusiness_type(), new ArrayList<WxTemplate>());

						template.setTemplateUrlMap(instanceReplaceValues(template.getTemplate_url()));
						template.setFirstValueMap(instanceReplaceValues(template.getContent_value()));
						template.setKeyword1ValueMap(instanceReplaceValues(template.getKeyword1_value()));
						template.setKeyword2ValueMap(instanceReplaceValues(template.getKeyword2_value()));
						template.setKeyword3ValueMap(instanceReplaceValues(template.getKeyword3_value()));
						template.setKeyword4ValueMap(instanceReplaceValues(template.getKeyword4_value()));
						template.setKeyword5ValueMap(instanceReplaceValues(template.getKeyword5_value()));
						template.setRemarkValueMap(instanceReplaceValues(template.getRemark_value()));
						templateMap.get(template.getBusiness_type()).add(template);

					}
				} catch (Exception e) {
					LogHelper.warn("模块[" + module.getModule_alias() + "]启动失败：未找到微信模版消息表[WX_TEMPLATE]");
				}

				// 文本消息自动回复
				wx.setMsgReplyMap(replyMap);
				// 消息处理器
				wx.setProcessorMap(processorMap);
				// 模版消息
				wx.setTemplateMap(templateMap);
				// 参数信息
				wx.setParamMap(paramMap);
				/***************
				 * 如果没有启动tokent线程，启动线程
				 */
				if (wx.getTokenThread() == null) {
					// 获取token线程启动
					TokenRequestThread t = new TokenRequestThread(wx.getApp_id());
					t.start();
					wx.setTokenThread(t);
				}

			}
		}

	}

	private static Map<String, String> instanceReplaceValues(String source) {
		Map<String, String> map = new HashMap<String, String>();
		if (StringHelper.isEmpty(source))
			return map;
		for (int i = 0; i < source.length(); i++) {
			// 获取到第一个@{,判断下一个是否为｛
			if (i + 3 < source.length() && source.substring(i, i + 2).equals("@{")) {
				// 判断下一个}
				String str = "", rightValue = source.substring(i + 2);
				if (rightValue.indexOf("}") > -1) {
					str = rightValue.substring(0, rightValue.indexOf("}"));
					i = i + 2 + str.length();
					map.put(str, str);
				} else
					break;
			}
		}
		return map;
	}
}
