package com.gxwebsoft.open.controller;

import cn.hutool.http.HttpUtil;
import com.gxwebsoft.common.core.annotation.OperationLog;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.security.JwtSubject;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.CommonUtil;
import com.gxwebsoft.common.core.utils.WxWorkUtil;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.common.core.web.BaseController;
import com.gxwebsoft.common.system.entity.LoginRecord;
import com.gxwebsoft.common.system.entity.User;
import com.gxwebsoft.common.system.entity.UserRole;
import com.gxwebsoft.common.system.param.UserParam;
import com.gxwebsoft.common.system.result.LoginResult;
import com.gxwebsoft.common.system.service.LoginRecordService;
import com.gxwebsoft.common.system.service.SettingService;
import com.gxwebsoft.common.system.service.UserRoleService;
import com.gxwebsoft.common.system.service.UserService;
import com.gxwebsoft.shop.entity.UserOauth;
import com.gxwebsoft.shop.param.UserOauthParam;
import com.gxwebsoft.shop.service.UserOauthService;
import com.qq.weixin.mp.aes.AesException;
import com.qq.weixin.mp.aes.WXBizJsonMsgCrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;

/**
 * 企业微信接口
 *
 * @author WebSoft
 * @since 2022-11-19 13:54:27
 */
@Api(tags = "企业微信验证")
@RestController
@RequestMapping("/api/open/wx-work")
public class OpenWxWorkController extends BaseController {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ConfigProperties configProperties;
    @Resource
    private WxWorkUtil workUtil;
    @Resource
    private UserService userService;
    @Resource
    private UserOauthService userOauthService;
    @Resource
    private LoginRecordService loginRecordService;
    @Resource
    private SettingService settingService;
    @Resource
    private UserRoleService userRoleService;

    @OperationLog
    @ApiOperation("第一步：请求验证URL有效性")
    @GetMapping()
    public String msgSignature(HttpServletRequest request) throws AesException {
      String sToken = "gFJXh4y2QAg5gm6U";
      String sCorpID = "wxa040285bc1c223ae";
      String sEncodingAESKey = "MRYqPeaVleIZDzgS2O8CoyyRwAYBOD9wQAztSfLMWaA";

      WXBizJsonMsgCrypt wxcpt = new WXBizJsonMsgCrypt(sToken, sEncodingAESKey, sCorpID);

      // 解析出url上的参数值如下：
      final String sVerifyMsgSig = request.getParameter("msg_signature");
      final String sVerifyTimeStamp = request.getParameter("timestamp");
      final String sVerifyNonce = request.getParameter("nonce");
      final String sVerifyEchoStr = request.getParameter("echostr");
      String sEchoStr; //需要返回的明文
      System.out.println("sVerifyMsgSig = " + sVerifyMsgSig);
      System.out.println("sVerifyTimeStamp = " + sVerifyTimeStamp);
      System.out.println("sVerifyNonce = " + sVerifyNonce);
      System.out.println("sVerifyEchoStr = " + sVerifyEchoStr);

      try {
        sEchoStr = wxcpt.VerifyURL(sVerifyMsgSig, sVerifyTimeStamp,
          sVerifyNonce, sVerifyEchoStr);
        System.out.println("verifyurl echostr: " + sEchoStr);
        // 验证URL成功，将sEchoStr返回
        return sEchoStr;
      } catch (Exception e) {
        //验证URL失败，错误原因请查看异常
        e.printStackTrace();
      }
      return "验证失败";
    }

    @ApiOperation("获取access_token并登录")
    @GetMapping("/saveAccessToken")
    public ApiResult<?> saveAccessToken(HttpServletRequest request, HttpServletResponse resp) throws IOException {
      System.out.println("request = " + request);
      final String code = request.getParameter("code");
      final String state = request.getParameter("state");
      final Integer tenantId = Integer.valueOf(state);
      System.out.println("code = " + code);
      System.out.println("state = " + state);
      // 1.实例化
      WxWorkUtil client = workUtil.client(tenantId);
      // 2.获取access_token
      String key = "cache"+ tenantId +":ww:access_token";
      String access_token = stringRedisTemplate.opsForValue().get(key);
      System.out.println("access_token_cache = " + access_token);
      if (access_token == null){
        client.getAccessToken(code);
      }
      // 3.获取用户信息
      client.getUserInfo(code,access_token);

      // 3.2 读取用户详细信息
      client.getUserProfile(client.userid,access_token);

      // 4.查询第三方用户信息表
      UserOauthParam userOauthParam = new UserOauthParam();
      userOauthParam.setOauthId(client.userid);
      userOauthParam.setUnionid(client.userid);
      userOauthParam.setTenantId(tenantId);
      System.out.println("userOauthParam = " + userOauthParam);
      final UserOauth oauthUser = userOauthService.getByUnionId(userOauthParam);
      System.out.println("oauthUser = " + oauthUser);

      // 4.1存在签发token
      if(oauthUser != null){
        UserParam userParam = new UserParam();
        userParam.setUserId(oauthUser.getUserId());
        userParam.setTenantId(tenantId);
        System.out.println("userParam = " + userParam);
        User user = userService.getByUnionId(userParam);
        // 5.签发token
        System.out.println("user = 签发token " + user);
        String ww_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), tenantId),
          configProperties.getTokenExpireTime(), configProperties.getTokenKey());
        resp.sendRedirect("http://apps.gxwebsoft.com/baocan/#/?ww_token=" + ww_token + "&userId=" + user.getUserId());
        return success("登录成功",new LoginResult(ww_token, user));
      }
      // 4.2不存在则注册并登录签发token
      User user = new User();
      user.setNickname(client.name);
      user.setUsername(client.userid);
      user.setPhone(client.mobile);
      user.setSex(client.gender);
      user.setPosition(client.position);
      user.setEmail(client.email);
      user.setAlias(client.alias);
      user.setPassword(userService.encodePassword(CommonUtil.randomUUID16()));
      user.setPlatform("WX-WORK");
      user.setTenantId(tenantId);
      userService.saveUser(user);
      System.out.println("userLast = " + user);
      // 添加默认角色
      UserRole userRole = new UserRole();
      userRole.setRoleId(241);
      userRole.setUserId(user.getUserId());
      userRole.setTenantId(tenantId);
      userRoleService.save(userRole);
      // 添加第三方用户信息
      UserOauth userOauth = new UserOauth();
      userOauth.setTenantId(tenantId);
      userOauth.setOauthType("WX-WORK");
      userOauth.setOauthId(client.userid);
      userOauth.setUnionid(client.userid);
      userOauth.setUserId(user.getUserId());
      userOauthService.save(userOauth);
      loginRecordService.saveAsync(user.getUsername(), LoginRecord.TYPE_LOGIN, null, tenantId, request);
      // 5.签发token
      String ww_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), tenantId),
        configProperties.getTokenExpireTime(), configProperties.getTokenKey());
      resp.sendRedirect("http://apps.gxwebsoft.com/baocan/#/?ww_token=" + ww_token + "&userId=" + user.getUserId());
      return success("注册成功",new LoginResult(ww_token, user));
    }
}
