package cn.hmsoft.weixin.service;

import java.net.InetAddress;
import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.log.LogHelper;
import cn.hmsoft.weixin.data.dao.WxDefineDao;
import cn.hmsoft.weixin.data.model.WxDefine;
import cn.hmsoft.weixin.entity.response.TicketResponseJson;
import cn.hmsoft.weixin.entity.response.TokenResponseJson;
import cn.hmsoft.weixin.request.TicketGetRequest;
import cn.hmsoft.weixin.request.TokenRequest;
import cn.hmsoft.weixin.util.WeiXinParamUtil;

/*****************
 * 获取token的service，考虑到集群环境，这里用锁定数据库的方式来确保唯一获取
 *
 */
@Service
public class WxTokenService {
	@Autowired
	private WxDefineDao daoWeixin;

	@Transactional(isolation = Isolation.SERIALIZABLE)
	public void fetchTokenFromWeixin(WxDefine wxDefine, InetAddress addr) {
		// 更新
		String sql = "update wx_define set wx_code=? where app_id=?";
		this.daoWeixin.updateBySql(sql, LocalDateHelper.format(LocalDateTime.now()), wxDefine.getApp_id());
		TokenRequest rq = new TokenRequest();
		rq.setWxDefine(wxDefine);
		TokenResponseJson response = null;
		int requestTotal = 0;
		do {
			try {
				response = rq.request();
				if (StringHelper.isNotEmpty(response.getAccess_token())) {
					// 写入数据库
					this.daoWeixin.updateBySql(
							"update wx_define set app_accesstoken=?,app_token_expired=?,wx_code=null where app_id=?",
							wxDefine.getApp_accesstoken(), wxDefine.getApp_token_expired(), wxDefine.getApp_id());
				}
			} catch (Exception e) {
				requestTotal++;
				response = null;
				try {
					Thread.sleep(WeiXinParamUtil.TokenIntervalSeconds * 1000);
				} catch (Exception ex) {

				}
			}
		} while (response == null && requestTotal < WeiXinParamUtil.TokenRetryTimes);
		if (response == null || response.getErrcode() != 0) {
			LogHelper.error("------[" + (addr == null ? "" : addr.getHostAddress()) + "]  [" + wxDefine.getWx_name()
					+ "] Token获取失败：" + response == null ? "网络错误" : response.getErrmsg() + "------");
			try {
				this.daoWeixin.updateBySql("update wx_define set wx_code=null where app_id=?", wxDefine.getApp_id());
			} catch (Exception e) {
			}
			return;
		}
		LogHelper.info("------[" + (addr == null ? "" : addr.getHostAddress()) + "]  [" + wxDefine.getWx_name()
				+ "] Token获取成功------");
		// 取ticket
		TicketGetRequest tr = new TicketGetRequest();
		tr.setWxDefine(wxDefine);
		TicketResponseJson json = null;
		requestTotal = 0;
		do {
			try {
				json = tr.request();
				if (StringHelper.isNotEmpty(json.getTicket())) {
					// 写入数据库
					this.daoWeixin.updateBySql("update wx_define set app_jsapi=? where app_id=?",
							wxDefine.getApp_jsapi(), wxDefine.getApp_id());
				} else {
					json = null;
				}
			} catch (Exception e) {
				requestTotal++;
				json = null;
				try {
					Thread.sleep(WeiXinParamUtil.TokenIntervalSeconds * 1000);
				} catch (Exception ex) {
				}
			}
		} while (json == null && requestTotal < WeiXinParamUtil.TokenRetryTimes);
	}

}
