package tech.easyflow.admin.controller.auth;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson2.JSONObject;
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 tech.easyflow.auth.entity.*;
import tech.easyflow.auth.service.AuthCredentialKeyService;
import tech.easyflow.auth.service.AuthService;
import tech.easyflow.common.captcha.tainai.CaptchaVerificationService;
import tech.easyflow.common.constant.Constants;
import tech.easyflow.common.domain.Result;
import tech.easyflow.common.entity.LoginAccount;
import tech.easyflow.common.satoken.util.SaTokenUtil;
import tech.easyflow.common.web.exceptions.BusinessException;
import tech.easyflow.common.web.jsonbody.JsonBody;
import tech.easyflow.log.annotation.LogRecord;

import javax.annotation.Resource;
import java.util.List;

@RestController
@RequestMapping("/api/v1/auth/")
public class AuthController {

    @Resource
    private AuthService authService;
    @Resource
    private AuthCredentialKeyService credentialKeyService;
    @Resource
    private CaptchaVerificationService captchaVerificationService;

    @GetMapping("credential-key")
    public Result<CredentialKeyVO> credentialKey() {
        return Result.ok(credentialKeyService.getCurrentCredentialKey());
    }

    @PostMapping("login")
    public Result<LoginVO> login(@JsonBody EncryptedCredentialDTO encryptedCredential) {
        JSONObject payload = credentialKeyService.decryptPayload(encryptedCredential);
        if (!captchaVerificationService.verify(payload.getString("validToken"))) {
            return captchaVerificationService.failureResult();
        }
        LoginDTO loginDTO = toLoginDTO(payload);
        LoginVO res = authService.login(loginDTO);
        return Result.ok(res);
    }

    @PostMapping("loginByApiKey")
    @SaIgnore
    public Result<LoginVO> loginByApiKey(@JsonBody(value = "apiKey", required = true) String apiKey) {
        return Result.ok(authService.loginByApiKey(apiKey));
    }

    @PostMapping("logout")
    public Result<Void> logout() {
        StpUtil.logout();
        return Result.ok();
    }

    @GetMapping("getPermissions")
    public Result<List<String>> getPermissions() {
        List<String> permissionList = StpUtil.getPermissionList();
        return Result.ok(permissionList);
    }

    @PostMapping("credential-key/rotate")
    @LogRecord("轮换认证传输密钥")
    public Result<Void> rotateCredentialKey(@JsonBody CredentialKeyRotateDTO rotateDTO) {
        StpUtil.checkLogin();
        LoginAccount loginAccount = SaTokenUtil.getLoginAccount();
        if (loginAccount == null || !Constants.SUPER_ADMIN_ID.equals(loginAccount.getId())) {
            throw new BusinessException("仅超级管理员可轮换认证密钥");
        }
        credentialKeyService.rotate(rotateDTO != null && Boolean.TRUE.equals(rotateDTO.getEmergency()));
        return Result.ok();
    }

    private LoginDTO toLoginDTO(JSONObject payload) {
        LoginDTO loginDTO = new LoginDTO();
        loginDTO.setAccount(payload.getString("account"));
        loginDTO.setPassword(payload.getString("password"));
        return loginDTO;
    }
}
