package com.zhangmeng.oauth.controller;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.zhangmeng.api.service.oauth.AuthControllerApi;
import com.zhangmeng.model.base.baseController.BaseController;
import com.zhangmeng.model.bean.TokenTools;
import com.zhangmeng.model.entity.OauthConfig;
import com.zhangmeng.model.entity.User;
import com.zhangmeng.model.vo.Result;
import com.zhangmeng.model.vo.StatusCode;
import com.zhangmeng.oauth.dto.AuthToken;
import com.zhangmeng.oauth.feign.AdminFeign;
import com.zhangmeng.oauth.service.AuthService;
import com.zhangmeng.oauth.service.OauthConfigService;
import com.zhangmeng.oauth.utils.CookieUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletResponse;
import java.util.Map;

@RestController
@RequestMapping(value = "/user")
public class AuthController extends BaseController implements AuthControllerApi {

    @Autowired
    private AdminFeign adminFeign;

    @Autowired
    private OauthConfigService oauthConfigService;

    @Autowired
    private AuthService authService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    private TokenTools tokenTools;

    @Override
    @GetMapping("/oauth/parseToken")//解析
    public Map<String, Object> parseToken(String token) {
        return this.tokenTools.dcodeToken(token);
    }

    @Override
    @PostMapping("/login")
    public Result login(String username, String password) {
        if (StringUtils.isEmpty(username)) {
            throw new RuntimeException("用户名不允许为空");
        }
        if (StringUtils.isEmpty(password)) {
            throw new RuntimeException("密码不允许为空");
        }
        User user = this.adminFeign.findByUserName(username);
        if (user == null){
            throw new UsernameNotFoundException("用户名错误");
        }
        //校验密码是否正确，如果正确则申请令牌
        if (!this.passwordEncoder.matches(password,user.getPassword())) {
            throw new RuntimeException("密码错误");
        }
        OauthConfig oauthConfig = this.oauthConfig();
        AuthToken authToken = auth_login(username, password,oauthConfig);
        //用户身份令牌
        String access_token = authToken.getAccessToken();
        //将令牌存储到cookie
        saveCookie(access_token,oauthConfig);
        return new Result(true, StatusCode.OK, "登录成功！",authToken);
    }

    private AuthToken auth_login(String username, String password,OauthConfig oauthConfig){
        //客户端ID
        String clientId = oauthConfig.getClientId();
        //秘钥
        String clientSecret = oauthConfig.getClientSecret();
        //申请令牌
        return this.authService.login(username, password, clientId, clientSecret);
    }

    private OauthConfig oauthConfig(){
        OauthConfig oauthConfig = this.oauthConfigService.oauthConfig();
        if (oauthConfig == null) {
            throw new RuntimeException("oauthConfig 配置读取错误");
        }
        return oauthConfig;
    }

    /***
     * 将令牌存储到cookie
     * @param token
     */
    private void saveCookie(String token,OauthConfig oauthConfig) {
        //Cookie存储的域名
        String cookieDomain = oauthConfig.getCookieDomain();
        //Cookie生命周期
        int cookieMaxAge = oauthConfig.getCookieMaxAge();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        CookieUtil.addCookie(response, cookieDomain, "/", "Authorization", token, cookieMaxAge, false);
    }
}
