package com.cpop.core.handler;

import com.alibaba.fastjson.JSONObject;
import com.cpop.common.constant.Constants;
import com.cpop.core.base.R;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.enums.OperationLogEnum;
import com.cpop.core.base.enums.UserType;
import com.cpop.core.service.CoreService;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.JwtUtils;
import com.cpop.core.utils.MessageUtils;
import com.cpop.core.utils.SpringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author: DB
 * @date: 2022-09-25 16:56
 * @Description: 登出成功处理器
 */
@Component
public class JwtLogoutSuccessHandler implements LogoutSuccessHandler {
    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private RedisService redisService;

    @Override
    public void onLogoutSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException {
        if (authentication != null) {
            new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication);
        }
        String jwt = httpServletRequest.getHeader(jwtUtils.getHeader());
        //添加退出登录成功日志
        Jws<Claims> jws = jwtUtils.getClaimsByToken(jwt);
        Claims claim = jws.getBody();
        if (claim == null) {
            throw new JwtException("token 异常");
        }
        if (jwtUtils.isTokenExpired(claim)) {
            throw new JwtException("token 已过期");
        }
        String identification = claim.getSubject();
        UserType userType = UserType.valueOf(jws.getHeader().get(Constants.USER_TYPE).toString());
        //从缓存中获取
        JSONObject jsonObject = redisService.getCacheObject(userType.getKey() + identification);
        if (null != jsonObject) {
            LoginUser loginUser = jsonObject.toJavaObject(LoginUser.class);
            SpringUtils.getBean(CoreService.class).insertOperationLog(Constants.SUCCESS, OperationLogEnum.SYSTEM_LOGOUT, loginUser, MessageUtils.message("i18n_operationLog_systemLogout"));
        }
        //清除缓存
        redisService.deleteObject(userType.getKey() + identification);
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        String header = jwtUtils.getHeader();
        httpServletResponse.setHeader(header, "");
        R<String> result = R.ok(MessageUtils.message("i18n_loginOut_success"));
        outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }

}
