package com.samsung.interceptor;

import com.samsung.authentication.Account;
import com.samsung.common.util.JwtUtil;
import com.samsung.core.exception.*;
import com.samsung.role.RoleService;
import com.samsung.user.UserService;
import com.samsung.user.entity.User;
import io.jsonwebtoken.JwtException;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;


import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@Log4j2
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired
    JwtUtil jwtUtil;

    @Autowired
    RoleService roleService;

    @Value("${security.check.duplicate.login:false}")
    private boolean checkDuplicateLogin;

    @Autowired
    UserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("x-auth-token");
        // Token 값 유무
        if (StringUtils.isEmpty(token)) {
            throw new NotFoundTokenException("Not Found Token");
        }

        String userId;
        try {
            userId = jwtUtil.getUserIdFromToken(token);
        } catch (JwtException ex) {
            throw new InvalidTokenException("Invalid Token");
        }

        User user = userService.getUserById(userId);
        String originalUserId = request.getHeader("original-user-id");

        if (ObjectUtils.isEmpty(user)) {
            // token이 있으면서 시스템 사용자가 아닐 경우는 없음
            throw new NoSearchUserException("No Search User");
        } else {
            if (checkDuplicateLogin && StringUtils.isEmpty(originalUserId) && StringUtils.isNotEmpty(user.getJwt())) {
                checkDuplicateLogin(token, user);
            }
            Boolean jwtValid = jwtUtil.validateToken(token, user);
            if (Boolean.TRUE.equals(jwtValid)) {
                if (user.isActiveFlag()) {
                    user.setSystemAdminUser(roleService.isSystemAdmin(userId));
                    Account.updateCurrentAccount(user);
                    return true;
                } else {
                    // 시스템 승인 대기중
                    throw new WaitingUserException("Waiting User");
                }
            } else {
                throw new InvalidTokenException("Token Expired");
            }
        }
    }

    private void checkDuplicateLogin(String token, User user) {
        //중복 로그인 방지 현재 로그인된 JWT토큰과 현재 토큰값을 비교
        if (!user.getJwt().equals(token.split("\\.")[2])) {
            throw new DuplicateLoginException("Duplicate Login!");
        }
    }
}
