package com.qs.mp.framework.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.common.enums.ErrorCodeEnum;
import com.qs.mp.common.enums.WxActTypeEnum;
import com.qs.mp.common.exception.ServiceException;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.StringUtils;
import com.qs.mp.common.utils.http.HttpUtils;
import com.qs.mp.framework.domain.WxAccount;
import com.qs.mp.framework.mapper.WxAccountMapper;
import com.qs.mp.framework.service.IAppTokenService;
import com.qs.mp.framework.service.IWxAccountService;
import com.qs.mp.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 微信用户表 服务实现类
 * </p>
 *
 * @author ygp
 * @since 2021-09-24
 */
@Service
public class WxAccountServiceImpl extends ServiceImpl<WxAccountMapper, WxAccount> implements
    IWxAccountService {

  protected final Logger logger = LoggerFactory.getLogger(WxAccountServiceImpl.class);

  @Value("${wxgzh.appId}")
  private String appId;

  @Autowired
  private IAppTokenService appTokenService;

  @Autowired
  private ISysUserService sysUserService;

  @Override
  @Transactional
  public boolean followGzh(String openid) {
    // 获取access_token
    String res = getUserInfo(openid, appId);
    LogUtil.info(logger, "weixin user info : {0} ", res);
    if (StringUtils.isBlank(res)) {
      LogUtil.error(logger, "获取微信用户信息为空，openId:{0}, appId:{1}", openid, appId);
      return false;
    }
    JSONObject jsonObject = JSON.parseObject(res);
    String unionid = jsonObject.getString("unionid");
    String nickname = jsonObject.getString("nickname");

    WxAccount wxAccount = getBaseMapper().selectOne(
        new QueryWrapper<WxAccount>().lambda().eq(WxAccount::getOpenid, openid));
    if (wxAccount != null) {
      LogUtil.info(logger, "关注公众号事件处理时，账户已经存在，消息忽略，openid:{0}", openid);
      return true;
    }

    // 保存账户信息
    WxAccount newWxAccount = new WxAccount();
    newWxAccount.setOpenid(openid);
    newWxAccount.setUnionid(unionid);
    newWxAccount.setNickName(nickname);
    newWxAccount.setActType(WxActTypeEnum.GZH);
    save(newWxAccount);

    // 更新sysuser表中的公众号openid
    int rst = sysUserService.updateUserGzhOpenId(unionid, openid);
    LogUtil.info(logger, "更新用户的关注公众号openid的记录数为:{0}, unionid:{1}, openid:{2}",
        new Object[]{rst, unionid, openid});
    return true;
  }

  @Override
  @Transactional
  public boolean unFollowGzh(String openid) {
    WxAccount wxAccount = getBaseMapper().selectOne(
        new QueryWrapper<WxAccount>().lambda().eq(WxAccount::getOpenid, openid));
    if (wxAccount == null) {
      LogUtil.warn(logger, "取消关注公众号事件处理时，账户不存在，消息忽略，openid:{0}", openid);
      return true;
    }
    remove(new QueryWrapper<WxAccount>().lambda().eq(WxAccount::getOpenid, openid));

    // 把sysuser表中该用户的公众号openid清除
    int rst = sysUserService.updateUserGzhOpenId(wxAccount.getUnionid(), null);
    LogUtil.info(logger, "清除用户的关注公众号openid的记录数为:{0}, unionid:{1}, openid:{2}",
        new Object[]{rst, wxAccount.getUnionid(), openid});
    return true;
  }

  @Override
  public String getUserInfo(String openid, String appId) {
    String accessToken = appTokenService.getAccessToken(appId);
    String url = "https://api.weixin.qq.com/cgi-bin/user/info";
    String params = "access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
    String res = HttpUtils.sendGet(url, params);
    JSONObject result = JSON.parseObject(res);
    String errcode = result.getString("errcode");
    if (StringUtils.isNotBlank(errcode)){
      LogUtil.error(logger, "查询微信用户信息错误，res:{0}", res);
      throw new ServiceException(ErrorCodeEnum.ERROR_CODE_1012);
    }
    return res;
  }
}
