package com.sf.oauth.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.sf.common.constant.Constants;
import com.sf.common.constant.HttpStatus;
import com.sf.common.core.domain.AjaxResult;
import com.sf.oauth.config.AuthConfig;
import com.sf.oauth.domain.AuthCallback;
import com.sf.oauth.domain.AuthUser;
import com.sf.oauth.enums.scope.AuthHuaweiScope;
import com.sf.oauth.exception.AuthException;
import com.sf.oauth.request.AuthHuaweiRequest;
import com.sf.oauth.request.AuthRequest;
import com.sf.oauth.service.IAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Arrays;

import static org.apache.commons.lang3.StringUtils.EMPTY;

/**
 * @author zoukun
 */
@Slf4j
@RestController
@RequestMapping("/oauth")
public class RestAuthController {

    @Autowired
    private IAuthService authService;

    @GetMapping("/authorize/{source}")
    public void authorize(@PathVariable("source") String source, HttpServletResponse response) throws IOException {
        log.info("进入render：" + source);
        AuthRequest authRequest = getAuthRequest(source, EMPTY, EMPTY);
        String authorizeUrl = authRequest.authorize(UUID.fastUUID().toString());
        log.info(authorizeUrl);
        response.sendRedirect(authorizeUrl);
    }

    /**
     * oauth平台中配置的授权回调地址
     * 如在创建华为授权应用时的回调地址为：http://127.0.0.1:8080/oauth/callback/huawei
     */
    @RequestMapping("/callback/{source}")
    public AjaxResult callback(@PathVariable("source") String source, @RequestBody AuthCallback callback, HttpSession session) {
        log.info("进入callback：" + source + " callback params：" + JSONObject.toJSONString(callback));
        AuthRequest authRequest = getAuthRequest(source, callback.getClientId(), callback.getClientSecret());
        AuthUser authUser = authRequest.callback(callback);
        log.info(JSONObject.toJSONString(authUser));
        AjaxResult ajax = AjaxResult.success();
        String token = authService.authLogin(authUser,session);
        ajax.put(Constants.TOKEN, token);
        return ajax;
    }

    /*
    @RequestMapping("/revoke/{source}/{userId}")
    @ResponseBody
    public AjaxResult revokeAuth(@PathVariable("source") String source, @PathVariable("userId") String userId) throws IOException {
        AuthRequest authRequest = getAuthRequest(source.toLowerCase());

        AuthUser user = userService.getByUuid(uuid);
        if (null == user) {
            return Response.error("用户不存在");
        }
        AjaxResult<AuthToken> response = null;
        try {
            response = authRequest.revoke(user.getToken());
            if (response.ok()) {
                userService.remove(user.getUuid());
                return Response.success("用户 [" + user.getUsername() + "] 的 授权状态 已收回！");
            }
            return Response.error("用户 [" + user.getUsername() + "] 的 授权状态 收回失败！" + response.getMsg());
        } catch (AuthException e) {
            return Response.error(e.getErrorMsg());
        }
    }

    @RequestMapping("/refresh/{source}/{userId}")
    @ResponseBody
    public Object refreshAuth(@PathVariable("source") String source, @PathVariable("userId") String userId) {
        AuthRequest authRequest = getAuthRequest(source.toLowerCase());

        AuthUser user = userService.getByUuid(userId);
        if (null == user) {
            return Response.error("用户不存在");
        }
        AjaxResult<AuthToken> response = null;
        try {
            response = authRequest.refresh(user.getToken());
            if (response.ok()) {
                user.setToken(response.getData());
                userService.save(user);
                return Response.success("用户 [" + user.getUsername() + "] 的 access token 已刷新！新的 callback: " + response.getData().getAccessToken());
            }
            return Response.error("用户 [" + user.getUsername() + "] 的 access token 刷新失败！" + response.getMsg());
        } catch (AuthException e) {
            return Response.error(e.getErrorMsg());
        }
    }*/

    /**
     * 根据具体的授权来源，获取授权请求工具类
     *
     * @param source
     * @return
     */
    private AuthRequest getAuthRequest(String source, String clientId, String clientSecret) {
        AuthRequest authRequest = null;
        switch (source.toLowerCase()) {
            case "huawei":
                authRequest = new AuthHuaweiRequest(AuthConfig.builder()
                        .clientId(StrUtil.isBlank(clientId) ? "110693217" : clientId)
                        .clientSecret(StrUtil.isBlank(clientSecret) ? "1410c01bc71c7ba587175ae79e500137c70945acc1416a38127cf98a09a6f8ba" : clientSecret)
                        .redirectUri("")
                        .ignoreCheckState(true)
                        .scopes(Arrays.asList(
                                AuthHuaweiScope.BASE_PROFILE.getScope(),
                                AuthHuaweiScope.MOBILE_NUMBER.getScope(),
                                AuthHuaweiScope.ACCOUNTLIST.getScope(),
                                AuthHuaweiScope.SCOPE_DRIVE_FILE.getScope(),
                                AuthHuaweiScope.SCOPE_DRIVE_APPDATA.getScope()
                        ))
                        .build());
                break;
            default:
                break;
        }
        if (null == authRequest) {
            throw new AuthException(HttpStatus.BAD_REQUEST, "未获取到有效的Auth配置");
        }
        return authRequest;
    }
}
