/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称:
 * 创建日期:2023/12/27
 */
package org.springblade.modules.auth.endpoint;

import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.wf.captcha.SpecCaptcha;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.jwt.JwtUtil;
import org.springblade.core.jwt.props.JwtProperties;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.WebUtil;
import org.springblade.modules.auth.provider.ITokenGranter;
import org.springblade.modules.auth.provider.TokenGranterBuilder;
import org.springblade.modules.auth.provider.TokenParameter;
import org.springblade.modules.auth.utils.TokenUtil;
import org.springblade.modules.system.entity.UserInfo;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.time.Duration;
import java.util.UUID;

/***
 * Date:2023/12/27
 * Title:文件所属模块（必须填写）
 * Description：对本文件的详细描述，原则上不能少于30字
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@NonDS
@ApiSort(1)
@RestController
@RequestMapping({"galaxy-auth"})
@Api(
        value = "用户授权认证",
        tags = {"授权接口"}
)
public class BladeTokenEndPoint {
    private final BladeRedis bladeRedis;
    private final JwtProperties jwtProperties;

    @ApiLog("登录用户验证")
    @PostMapping({"/oauth/token"})
    @ApiOperation(
            value = "获取认证令牌",
            notes = "传入租户ID:tenantId,账号:account,密码:password"
    )
    public Kv token(@ApiParam(value = "租户ID",required = true) @RequestParam String tenantId, @ApiParam(value = "账号",required = true) @RequestParam(required = false) String username, @ApiParam(value = "密码",required = true) @RequestParam(required = false) String password, @ApiIgnore @RequestHeader(name = "Dept-Id",required = false) String deptId, @ApiIgnore @RequestHeader(name = "Role-Id",required = false) String roleId) {
        Kv authInfo = Kv.create();
        String grantType = WebUtil.getRequest().getParameter("grant_type");
        String refreshToken = WebUtil.getRequest().getParameter("refresh_token");
        String userType = Func.toStr(WebUtil.getRequest().getHeader("User-Type"), "web");
        TokenParameter tokenParameter = new TokenParameter();
        tokenParameter.getArgs().set("tenantId", tenantId).set("username", username).set("password", password).set("grantType", grantType).set("refreshToken", refreshToken).set("userType", userType).set("deptId", deptId).set("roleId", roleId);
        ITokenGranter granter = TokenGranterBuilder.getGranter(grantType);
        UserInfo userInfo = granter.grant(tokenParameter);
        if (userInfo != null && userInfo.getUser() != null) {
            if (2==userInfo.getUser().getUserType()){
                 if (!"app".equals(userType)){
                     return authInfo.set("error_code", 400).set("error_description", "用户权限不正确");
                 }
            }
            return Func.isEmpty(userInfo.getRoles()) ? authInfo.set("error_code", 400).set("error_description", "未获得用户的角色信息") : TokenUtil.createAuthInfo(userInfo);
        } else {
            return authInfo.set("error_code", 400).set("error_description", "用户名或密码不正确");
        }
    }

    @GetMapping({"/oauth/logout"})
    @ApiOperation("退出登录")
    public Kv logout() {
        BladeUser user = AuthUtil.getUser();
        if (user != null && this.jwtProperties.getState()) {
            String token = JwtUtil.getToken(WebUtil.getRequest().getHeader("Blade-Auth"));
            JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
        }

        return Kv.create().set("success", "true").set("msg", "success");
    }

    @GetMapping({"/oauth/captcha"})
    @ApiOperation("获取验证码")
    public Kv captcha() {
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        String verCode = specCaptcha.text().toLowerCase();
        String key = UUID.randomUUID().toString();
        this.bladeRedis.setEx("blade:auth::blade:captcha:" + key, verCode, Duration.ofMinutes(30L));
        return Kv.create().set("key", key).set("image", specCaptcha.toBase64());
    }

    @GetMapping({"/oauth/clear-cache"})
    @ApiOperation("清除缓存")
    public Kv clearCache() {
        CacheUtil.clear("blade:biz");
        CacheUtil.clear("blade:user");
        CacheUtil.clear("blade:dict");
        CacheUtil.clear("blade:flow");
        CacheUtil.clear("blade:sys");
        CacheUtil.clear("blade:param");
        CacheUtil.clear("blade:resource");
        CacheUtil.clear("blade:menu");
        CacheUtil.clear("blade:dict", Boolean.FALSE);
        CacheUtil.clear("blade:menu", Boolean.FALSE);
        CacheUtil.clear("blade:sys", Boolean.FALSE);
        CacheUtil.clear("blade:param", Boolean.FALSE);
        return Kv.create().set("success", "true").set("msg", "success");
    }

    public BladeTokenEndPoint(final BladeRedis bladeRedis, final JwtProperties jwtProperties) {
        this.bladeRedis = bladeRedis;
        this.jwtProperties = jwtProperties;
    }
}
