package com.gxwebsoft.open.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.gxwebsoft.common.core.config.ConfigProperties;
import com.gxwebsoft.common.core.exception.BusinessException;
import com.gxwebsoft.common.core.security.JwtSubject;
import com.gxwebsoft.common.core.security.JwtUtil;
import com.gxwebsoft.common.core.utils.AlipayConfigUtil;
import com.gxwebsoft.common.core.utils.CommonUtil;
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.UserRoleService;
import com.gxwebsoft.common.system.service.UserService;
import com.gxwebsoft.shop.entity.UserOauth;
import com.gxwebsoft.shop.mapper.UserOauthMapper;
import com.gxwebsoft.shop.param.UserOauthParam;
import com.gxwebsoft.shop.service.UserOauthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import static com.gxwebsoft.common.core.utils.CommonUtil.randomUsername;

/**
 * 登录认证控制器
 *
 * @author WebSoft
 * @since 2018-12-24 16:10:11
 */
@Api(tags = "登录认证")
@RestController
@RequestMapping("/api/open/login-alipay")
public class OpenAlipayController extends BaseController {
    @Resource
    private ConfigProperties configProperties;
    @Resource
    private UserService userService;
    @Resource
    private LoginRecordService loginRecordService;
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private UserOauthService userOauthService;
    @Resource
    private AlipayConfigUtil alipayConfig;
    @Resource
    private UserOauthMapper userOauthMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @ApiOperation("支付宝授权码")
    @PostMapping("/getAuthCode")
    @Transactional(rollbackFor = {Exception.class})
    public ApiResult<?> getAuthCode(@RequestBody UserParam param, HttpServletRequest req) throws AlipayApiException {
      // 验证签名
      isCheckSign();
      // 读取缓存信息
      String setting = stringRedisTemplate.opsForValue().get("cache"+param.getTenantId()+":setting:register");
      if(setting == null){
        throw new BusinessException("请先配置注册设置");
      }
      JSONObject jsonObject = JSONObject.parseObject(setting);
      String roleId = jsonObject.getString("roleId");
      // 实例化客户端
      DefaultAlipayClient alipayClient = alipayConfig.alipayClient(param.getTenantId());
      try {
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("authorization_code");
        request.setCode(param.getAuthCode());
        AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);
        if (response.isSuccess()) {
          final String accessToken = response.getAccessToken();
          AlipayUserInfoShareRequest request2 = new AlipayUserInfoShareRequest();
          AlipayUserInfoShareResponse userInfo = alipayClient.certificateExecute(request2, accessToken);
          String nickName = "支付宝用户";
          String avatar = "";
          if(StrUtil.isNotBlank(userInfo.getAvatar())){
            avatar = userInfo.getAvatar();
          }
          if (StrUtil.isNotBlank(userInfo.getNickName())) {
            nickName = userInfo.getNickName();
          }
          if(userInfo.isSuccess()){
            // 查询是否已注册
            UserOauthParam userOauthParam = new UserOauthParam();
            userOauthParam.setOauthId(userInfo.getUserId());
            userOauthParam.setTenantId(param.getTenantId());
            UserOauth userOauth = userOauthParam.getOne(userOauthMapper.getByOauthId(userOauthParam));
            if(userOauth != null){
              UserParam userParam = new UserParam();
              userParam.setUserId(userOauth.getUserId());
              userParam.setTenantId(userOauth.getTenantId());
              User user = userService.getByOauthId(userParam);
              if(user != null){
                // 签发token
                String access_token = JwtUtil.buildToken(new JwtSubject(user.getUsername(), user.getTenantId()),
                  configProperties.getTokenExpireTime(), configProperties.getTokenKey());
                return success("登录成功", new LoginResult(access_token, user));
              }
              userOauthService.removeById(userOauth.getId());
            }
            // 新注册用户
            User user = new User();
            user.setStatus(0);
            user.setUsername(randomUsername("Ali_"));
            user.setNickname(nickName);
            user.setAvatar(avatar);
            user.setCity(userInfo.getCity());
            user.setProvince(userInfo.getProvince());
            user.setPassword(userService.encodePassword(CommonUtil.randomUUID16()));
            user.setTenantId(param.getTenantId());
            boolean isSuccess = userService.saveUser(user);
            if(isSuccess){
              // 添加用户角色
              UserRole userRole = new UserRole();
              userRole.setUserId(user.getUserId());
              userRole.setTenantId(param.getTenantId());
              userRole.setRoleId(Integer.valueOf(roleId));
              userRoleService.save(userRole);
              // 添加第三方用户信息
              UserOauth userOauth2 = new UserOauth();
              userOauth2.setUserId(user.getUserId());
              userOauth2.setTenantId(param.getTenantId());
              userOauth2.setOauthType("MP-ALIPAY");
              userOauth2.setOauthId(userInfo.getUserId());
              userOauthService.save(userOauth2);

              UserParam userParam = new UserParam();
              userParam.setUserId(user.getUserId());
              userParam.setTenantId(user.getTenantId());
              User result = userService.getByOauthId(userParam);
              loginRecordService.saveAsync(result.getUsername(), LoginRecord.TYPE_REGISTER, null, result.getTenantId(), req);
              // 签发token
              String access_token = JwtUtil.buildToken(new JwtSubject(result.getUsername(), result.getTenantId()),
                configProperties.getTokenExpireTime(), configProperties.getTokenKey());
              return success("登录成功", new LoginResult(access_token, result));
            }
          }
        }
      } catch (AlipayApiException e) {
        e.printStackTrace();
      }
      return fail("支付宝授权失败");
    }

    @ApiOperation("授权手机号码")
    @PostMapping("/update")
    public ApiResult<User> updateInfo(@RequestBody User user) {
      user.setUserId(getLoginUserId());
      // 不能修改的字段
      user.setUsername(null);
      user.setPassword(null);
      user.setEmailVerified(null);
      user.setOrganizationId(null);
      user.setStatus(null);
      if (userService.updateById(user)) {
        return success(userService.getByIdRel(user.getUserId()));
      }
      return fail("保存失败", null);
    }
}
