package com.goafanti.common.utils.weChat;

import com.alibaba.fastjson.JSONObject;
import com.goafanti.common.constant.AFTConstants;
import com.goafanti.common.dao.AdminMapper;
import com.goafanti.common.error.BusinessException;
import com.goafanti.common.model.Admin;
import com.goafanti.common.utils.*;
import com.goafanti.core.shiro.token.TokenManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Component
public class WeChatUtils {


	@Value(value = "${wx.appId}")
	private String appId;
	@Value(value = "${wx.appSecret}")
	private String appSecret;
	@Value(value = "${wx.expense.appId}")
	private String expenseAppId;
	@Value(value = "${wx.expense.appSecret}")
	private String expenseAppSecret;
	@Value(value = "${wx.state}")
	private String wxState;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private AdminMapper adminMapper;


	/**
	 * 公出待审核通知
	 */
	private static final String PUBLIC_RELEASE_EXAMINE ="j7WH3EwQnxGxwuV2HwmJhryxySPE8vOiV5cVOpp-42I";
	/**
	 * 公出审核结果通知
	 */
	private static final String PUBLIC_RELEASE_EXAMINE_RESULT="pWia-KJPFwDM8ReDu_BOa9FJn31VFc81bp3yxfBmIRI";
	/**
	 * 公出待审核通知
	 */
	private static final String EXPENSE_RELEASE_EXAMINE ="0e2Te3WUa0fDPQnyE8TLmN_K06WLsB4fqm5qpo6npNo";
	/**
	 * 公出审核结果通知
	 */
	private static final String EXPENSE_RELEASE_EXAMINE_RESULT="rRPWzRcGY8BGwlk0xyjwR1RKdv3iRFXaU3bcK1300gw";
	private static final String PUBLIC_RELEASE_SEND_COPY="UGlNqF1VQsxYh6iVKrDuw_EkhrDNU6TXv4snGw4xze8";


	/**
	 * 推送地址
	 */
	private static  String send_url="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";




	/**
	 * 推送微信订阅信息，跳转为公出信息
	 * @param openid 发送对象微信openid
	 * @param type 状态 0驳回 1发起 2同意
	 * @param date 日期
	 * @param aname 发送者名称
	 * @param remarks 发送信息，不能大于十五个字
	 */
	public Integer addNotice(String openid ,Integer type,Integer id, Date date, String aname,String remarks) {
		Map<String, Object> map=new HashMap<String, Object>();
		String accessToken=getAccessToken();
		String url=send_url.replace("ACCESS_TOKEN", accessToken);
		map.put("access_token", accessToken);
		map.put("touser", openid);
		map.put("page", "pages/egressDetails/index?id="+id);
		map.put("miniprogram_state", wxState);
		if (type==1) {
			map.put("template_id", PUBLIC_RELEASE_EXAMINE);
			map.put("data",getPublicData(type,date, aname,remarks));
		}else {
			map.put("template_id", PUBLIC_RELEASE_EXAMINE_RESULT);
			map.put("data",getPublicData(type,date, aname,remarks));
		}
		return SendHttpPost(map, url);

	}


	/**
	 * 推送微信订阅信息，跳转为公出信息
	 * @param openid 发送对象微信openid
	 * @param id 公出id
	 * @param name 发起者名称
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @param typeName 类型名称
	 * @param plan 抄送说明
	 */
	public Integer addSendCopyNotice(String openid ,Integer id,String name, String startTime, String endTime, String typeName, String plan) {
		Map<String, Object> map=new HashMap<String, Object>();
		String accessToken=getAccessToken();
		String url=send_url.replace("ACCESS_TOKEN", accessToken);
		map.put("access_token", accessToken);
		map.put("touser", openid);
		map.put("page", "pages/egressDetails/index?id="+id);
		map.put("miniprogram_state", wxState);
		map.put("template_id", PUBLIC_RELEASE_SEND_COPY);
		map.put("data",getSendCopyData(name, startTime, endTime, typeName, plan));
		return SendHttpPost(map, url);

	}

	private Object getSendCopyData(String name, String startTime, String endTime, String typeName, String plan) {
		Map<String, Object> we=new HashMap<String, Object>();
		if (plan.length()>20)plan=plan.substring(0,17)+"...";
		Map<String, Object> v1=new HashMap<String, Object>();
		v1.put("value",name);
		we.put("thing1", v1);
		Map<String, Object> v2=new HashMap<String, Object>();
		v2.put("value", typeName);
		we.put("thing2", v2);
		Map<String, Object> v3=new HashMap<String, Object>();
		v3.put("value", plan);
		we.put("thing3", v3);
		Map<String, Object> v4=new HashMap<String, Object>();
		v4.put("value", startTime);
		we.put("time4", v4);
		Map<String, Object> v5=new HashMap<String, Object>();
		v5.put("value", endTime);
		we.put("time5", v5);
		return we;
	}

	private Integer SendHttpPost(Map<String, Object> map, String url) {
		JSONObject res= HttpUtils.httpPost(url, map);
		if (res.get("errcode")!=null) {
			LoggerUtils.error(this.getClass(),String.format("================errcode={%s}",res));
			LoggerUtils.error(this.getClass(),String.format("================data={%s}",map.get("data")));
			return res.getInteger("errcode");
		}else {
			return 1;
		}
	}

	/**
	 * 推送微信订阅信息，跳转为报销信息
	 * @param openid 发送对象微信openid
	 * @param type 状态 0驳回 1发起 2同意
	 * @param date 日期
	 * @param aname 发送者名称
	 * @param remarks 发送信息，不能大于十五个字
	 */
	public Integer addExpenseAccountWeChatNotice(String openid ,Integer type,Integer id, Date date, String aname,String remarks) {
		if (openid==null )LoggerUtils.error(this.getClass(),"openId不能为空");
		Map<String, Object> map=new HashMap<String, Object>();
		String accessToken=getExpenseAccountAccessToken();
		String url=send_url.replace("ACCESS_TOKEN", accessToken);
		map.put("access_token", accessToken);
		map.put("touser", openid);
		//这里要替换成当前的
		map.put("page", "/pages/mergedetail/index?id="+id);
		map.put("miniprogram_state", wxState);
		if (type==1) {
			map.put("template_id", EXPENSE_RELEASE_EXAMINE);
			map.put("data",getExpenseData(type,date, aname,remarks));
		}else {
			map.put("template_id", EXPENSE_RELEASE_EXAMINE_RESULT);
			map.put("data",getExpenseData(type,date, aname,remarks));
		}
		LoggerUtils.debug(this.getClass(),"发送微信模版的参数为："+map.get("data"));
		return SendHttpPost(map, url);
	}

	/**
	 * 公出订阅消息组装
	 * @param type
	 * @param date
	 * @param aname
	 * @param remarks
	 * @return
	 */
	private Map<String, Object> getPublicData(Integer type,Date date, String aname, String remarks) {
		Map<String, Object> we=new HashMap<String, Object>();
		String strDate= DateUtils.formatDate(date, AFTConstants.YMDHMS_CHINESE);
		if (remarks.length()>20)remarks=remarks.substring(0,17)+"...";
		if (type==1) {
			Map<String, Object> v1=new HashMap<String, Object>();
			v1.put("value",strDate);
			we.put("time5", v1);
			Map<String, Object> v2=new HashMap<String, Object>();
			v2.put("value", aname);
			we.put("name3", v2);
			Map<String, Object> v3=new HashMap<String, Object>();
			v3.put("value", remarks);
			we.put("thing10", v3);
		}else {
			String thing2="";
			if (type==0){
				thing2="驳回";
			}else if (type==2){
				thing2="通过";
			}
			Map<String, Object> v1=new HashMap<String, Object>();
			v1.put("value",strDate);
			we.put("date3", v1);
			Map<String, Object> v2=new HashMap<String, Object>();
			v2.put("value", thing2);
			we.put("thing2", v2);
			Map<String, Object> v3=new HashMap<String, Object>();
			v3.put("value", remarks);
			we.put("thing6", v3);
		}
		return we;
	}


	/**
	 * 报销订阅消息组装
	 * @param type
	 * @param date
	 * @param aname
	 * @param remarks
	 * @return
	 */
	private Map<String, Object> getExpenseData(Integer type,Date date, String aname, String remarks) {
		Map<String, Object> we=new HashMap<String, Object>();
		String strDate=DateUtils.formatDate(date, AFTConstants.YMDHMS_CHINESE);
		if (remarks.length()>20)remarks=remarks.substring(0,17)+"...";
		if (type==1) {
			Map<String, Object> v2=new HashMap<String, Object>();
			we.put("thing4", v2);
			v2.put("value", aname);
			Map<String, Object> v1=new HashMap<String, Object>();
			we.put("time6", v1);
			v1.put("value",strDate);
			Map<String, Object> v3=new HashMap<String, Object>();
			we.put("thing2", v3);
			v3.put("value", remarks);
		}else {
			String thing5="";
			if (type==0){
				thing5="报销驳回";
			}else if (type==2){
				thing5="报销通过";
			}
			Map<String, Object> v1=new HashMap<String, Object>();
			we.put("time3", v1);
			v1.put("value",strDate);
			Map<String, Object> v2=new HashMap<String, Object>();
			we.put("thing5", v2);
			v2.put("value", thing5);
			Map<String, Object> v3=new HashMap<String, Object>();
			we.put("thing4", v3);
			v3.put("value", remarks);
		}
		return we;
	}




	public String getAccessToken() {
		Date date = new Date();
		if (redisUtil.presence("access_token")||redisUtil.presence("expires_in")) {
			String access_token=redisUtil.getString("access_token");
			String expires_in=redisUtil.getString("expires_in");
			if (date.getTime() < Long.valueOf(expires_in)) {
				LoggerUtils.debug(getClass(), "redis中获取accestoken");
				return access_token;
			} else {
				LoggerUtils.debug(getClass(), "accestoken超时重新获取");
				redisUtil.deleteString("access_token");
				redisUtil.deleteString("expires_in");
				return setSessionAccessToken(date,0);
			}

		} else {
			return setSessionAccessToken(date,0);
		}


	}

	public String getExpenseAccountAccessToken() {
		Date date = new Date();
		if (redisUtil.presence("expense_access_token")||redisUtil.presence("expense_expires_in")) {
			String access_token=redisUtil.getString("expense_access_token");
			String expires_in=redisUtil.getString("expense_expires_in");
			if (date.getTime() < Long.valueOf(expires_in)) {
				LoggerUtils.debug(getClass(), "redis中获取accestoken");
				return access_token;
			} else {
				LoggerUtils.debug(getClass(), "accestoken超时重新获取");
				redisUtil.deleteString("expense_access_token");
				redisUtil.deleteString("expense_expires_in");
				return setSessionAccessToken(date,1);
			}

		} else {
			return setSessionAccessToken(date,1);
		}


	}


	/**
	 *
	 * @param date 参数
	 * @param type 0公出小程序 1报销小程序
	 * @return
	 */
	private String setSessionAccessToken(Date date,Integer type) {
		String url =null;
		if (type==0){
			url=String.format(
					"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId,
					appSecret);
		}else if(type==1){
			url=String.format(
					"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", expenseAppId,
					expenseAppSecret);
		}

		JSONObject js = HttpUtils.httpGet(url);
		String errcode =js.getString("errcode");
		if (errcode!=null) {
			throw new  BusinessException("获取AccessToken失败！");
		}else {
			LoggerUtils.debug(AsyncUtils.class,"获取并存入AccessToken成功,accesstoken="+js.getString("access_token"));
		}
		String access_token = js.getString("access_token");
		Long expires_in = js.getLong("expires_in");
		//返回时间为秒需要计算换成毫秒
		expires_in=expires_in*1000;
		expires_in+=date.getTime();
		if (type==0){
			redisUtil.setString("access_token", access_token);
			redisUtil.setString("expires_in", expires_in.toString());
		}else if (type==1){
			redisUtil.setString("expense_access_token", access_token);
			redisUtil.setString("expense_expires_in", expires_in.toString());
		}

		return access_token;
	}

	public Integer setOpenId(String code, Integer type) {
		if(type==null)type=0;
		String url = "https://api.weixin.qq.com/sns/jscode2session?";
		if (type==1){
			url=url+"appid="+expenseAppId+"&secret="+expenseAppSecret+"&js_code="+code+"&grant_type=authorization_code";
		}else{
			url=url+"appid="+appId+"&secret="+appSecret+"&js_code="+code+"&grant_type=authorization_code";
		}
		JSONObject json= HttpUtils.httpGet(url);
		System.out.println(json.toJSONString());
		String openid=json.getString("openid");
		if (StringUtils.isNotBlank(openid)) {
			LoggerUtils.debug(getClass(), "获取"+(type==1?"报销":"公出")+"openid："+openid);
			Admin a=new Admin();
			if (type!=null&&type==1){
				a.setExpenseOpenId(openid);
			}else {
				a.setOpenId(openid);
			}
			a.setId(TokenManager.getAdminId());
			adminMapper.update(a);
			return 1;
		}else {
			return -1;
		}
	}
}
