package cn.reghao.bnt.web.admin.security.handler;

import cn.reghao.bnt.web.admin.model.dto.AccountInfo;
import cn.reghao.bnt.web.admin.model.vo.AccountLoginRet;
import cn.reghao.bnt.web.admin.model.vo.AccountToken;
import cn.reghao.bnt.web.admin.security.form.AccountAuthToken;
import cn.reghao.bnt.web.admin.service.AccountService;
import cn.reghao.bnt.web.admin.service.LoginAttemptService;
import cn.reghao.jutil.jdk.web.result.WebResult;
import cn.reghao.jutil.web.ServletUtil;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.savedrequest.SavedRequest;
import org.springframework.stereotype.Component;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 认证成功后的处理
 *
 * @author reghao
 * @date 2022-07-08 14:02:34
 */
@Component
public class AuthSuccessHandlerImpl implements AuthenticationSuccessHandler {
    private final LoginAttemptService loginAttemptService;
    private final AccountService accountService;

    public AuthSuccessHandlerImpl(LoginAttemptService loginAttemptService, AccountService accountService) {
        this.loginAttemptService = loginAttemptService;
        this.accountService = accountService;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth)
            throws IOException, ServletException {
        String sessionId = request.getSession().getId();
        AccountAuthToken accountAuthToken = (AccountAuthToken) auth;
        accountAuthToken.setLoginId(sessionId);
        loginAttemptService.saveLoginAttempts(accountAuthToken);

        String redirectPath = getRedirectPath(request.getSession());

        int userId = accountAuthToken.getUserId();
        String loginId = accountAuthToken.getLoginId();
        int loginType = accountAuthToken.getLoginType();
        int plat = accountAuthToken.getPlat();
        boolean rememberMe = accountAuthToken.isRememberMe();
        long timeout = rememberMe ? 3600*24*30 : 0;
        String uri = ServletUtil.getRequest().getRequestURI();
        if (uri.startsWith("/oauth/redirect")) {
            // 使用第三方帐号的 oauth 方式登入
            /*accountTokenService.setCookie(authToken, timeout);
            response.sendRedirect(redirectPath);
            return;*/
        }

        AccountInfo accountInfo = accountService.getAccountInfo();
        AccountToken accountToken = new AccountToken(sessionId);
        AccountLoginRet accountLoginRet = new AccountLoginRet(accountInfo, accountToken, redirectPath);

        String body = WebResult.success(accountLoginRet);
        writeResponse(response, body);
    }

    /**
     * 认证成功后, 重定向到登入前的地址, 需要 session 的支持
     *
     * @param
     * @return
     * @date 2023-08-16 10:58:41
     */
    private String getRedirectPath(HttpSession session) {
        String redirectPath = "/bg";
        // 获取 spring security 在 session 中存放的变量
        SavedRequest savedRequest = (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST");
        if (savedRequest != null) {
            redirectPath = savedRequest.getRedirectUrl();
        }

        return redirectPath;
    }

    private void writeResponse(HttpServletResponse response, String body) throws IOException {
        response.setContentType("application/json; charset=utf-8");
        PrintWriter printWriter = response.getWriter();
        printWriter.write(body);
    }
}
