package com.ningdatech.pmapi.user.security.auth.lisenter;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.ningdatech.log.model.OptLogDTO;
import com.ningdatech.log.model.enumeration.LogType;
import com.ningdatech.log.service.OptLogService;
import com.ningdatech.log.util.AddressUtil;
import com.ningdatech.pmapi.user.security.auth.model.UserInfoDetails;
import com.ningdatech.pmapi.user.security.auth.model.WebRequestDetails;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * <p>
 * AuthorizationEventListener
 * </p>
 *
 * @author WendyYang
 * @since 2023/6/7
 **/
@Component
@RequiredArgsConstructor
public class AuthorizationEventListener {

    private final OptLogService optLogService;

    @Async
    @EventListener(AuthenticationSuccessEvent.class)
    public void loginSuccessListener(AuthenticationSuccessEvent event) {
        optLogService.save(buildOptLog("用户登录", event));
    }

    @Async
    @EventListener(LogoutSuccessEvent.class)
    public void logoutSuccessListener(LogoutSuccessEvent event) {
        optLogService.save(buildOptLog("退出登录", event));
    }

    private OptLogDTO buildOptLog(String description, AbstractAuthenticationEvent event) {
        Authentication authentication = event.getAuthentication();
        UserInfoDetails userDetails = (UserInfoDetails) authentication.getPrincipal();
        WebRequestDetails webDetails = (WebRequestDetails) authentication.getDetails();
        LocalDateTime now = LocalDateTime.now();
        OptLogDTO optLog = new OptLogDTO();
        optLog.setActionMethod(webDetails.getServletPath());
        optLog.setDescription(description);
        optLog.setStartTime(LocalDateTimeUtil.of(event.getTimestamp()));
        optLog.setFinishTime(now);
        optLog.setCreateOn(now);
        long consumingTime = System.currentTimeMillis() - event.getTimestamp();
        optLog.setConsumingTime(consumingTime);
        optLog.setHttpMethod(webDetails.getMethod());
        optLog.setUserName(userDetails.getUsername());
        optLog.setCreateBy(userDetails.getUserId());
        optLog.setRequestIp(webDetails.getRequestIp());
        optLog.setRequestUri(webDetails.getRequestUri());
        optLog.setRegionByIp(AddressUtil.getRegion(optLog.getRequestIp()));
        optLog.setUa(webDetails.getUserAgent());
        optLog.setType(LogType.OPT.name());
        return optLog;
    }

}