package com.cpop.core.handler;

import com.alibaba.fastjson.JSONObject;
import com.cpop.common.constant.Constants;
import com.cpop.common.utils.ip.IpUtils;
import com.cpop.core.base.R;
import com.cpop.core.base.entity.LoginSuccess;
import com.cpop.core.base.entity.LoginUser;
import com.cpop.core.base.entity.loginInfo.MiniUserLoginInfo;
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 org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
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:19
 * @Description: 登录成功handler
 */
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private CoreService coreService;

    @Autowired
    private RedisService redisService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException{
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();
        LoginSuccess loginSuccessVo = new LoginSuccess();
        LoginUser loginUser;
        if (null != authentication.getCredentials()) {
            loginUser = (LoginUser) authentication.getCredentials();
        } else {
            loginUser = (LoginUser) authentication.getDetails();
        }
        // 生成JWT，并放置到请求头中
        String jwt = jwtUtils.generateToken(loginUser.getIdentification(), loginUser.getUsername(), loginUser.getUserType());
        loginSuccessVo.setToken(jwt).setUserId(loginUser.getUserId()).setRole(loginUser.getPermissions());
        String ipAddr = IpUtils.getIpAddr(httpServletRequest);
        loginUser.setIpAddr(ipAddr);
        //多种登陆方式
        multipleLogin(loginUser);
        R<LoginSuccess> result = R.ok(loginSuccessVo, MessageUtils.message("i18n_login_success"));
        outputStream.write(JSONObject.toJSONString(result).getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
    }

    /**
     * @Description: 多种登陆方式
     * @param loginUser 登陆用户
     * @author DB
     * @Date: 2023/8/24 0024 17:12
     */
    private void multipleLogin(LoginUser loginUser){
        switch (loginUser.getUserType()) {
            case OAM_USER:
            case MALL_USER:
                //更新登录地址
                coreService.updateSysUserLoginIp(loginUser.getIpAddr(), loginUser.getUsername(), loginUser.getUserType());
                //添加登录成功日志
                coreService.insertOperationLog(Constants.SUCCESS, OperationLogEnum.SYSTEM_LOGIN, loginUser, MessageUtils.message("i18n_login_success"));
                break;
            case MINI_USER:
                break;
            default:
        }
        //将登录成功用户存入缓存
        redisService.setCacheObject(loginUser.getUserType().getKey() + loginUser.getIdentification(), loginUser);
    }
}
