import com.shareaccount.backend.util.JwtTokenHelper;  
import io.jsonwebtoken.ExpiredJwtException;  
import io.jsonwebtoken.MalformedJwtException;  
import io.jsonwebtoken.UnsupportedJwtException;  
import io.jsonwebtoken.security.SignatureException;  
import io.micrometer.common.util.StringUtils;  
import jakarta.annotation.Resource;  
import jakarta.servlet.FilterChain;  
import jakarta.servlet.ServletException;  
import jakarta.servlet.http.HttpServletRequest;  
import jakarta.servlet.http.HttpServletResponse;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.security.authentication.AuthenticationServiceException;  
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;  
import org.springframework.security.core.context.SecurityContextHolder;  
import org.springframework.security.core.userdetails.UserDetails;  
import org.springframework.security.core.userdetails.UserDetailsService;  
import org.springframework.security.web.AuthenticationEntryPoint;  
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;  
import org.springframework.stereotype.Component;  
import org.springframework.web.filter.OncePerRequestFilter;  
  
import java.io.IOException;  
import java.util.Objects;  
  
@Component  
@Slf4j  
public class JwtAuthenticationFilter extends OncePerRequestFilter {  
  
    @Resource  
    JwtTokenHelper jwtTokenHelper;  
    @Resource  
    UserDetailsService userDetailsService;  
    @Resource  
    AuthenticationEntryPoint authenticationEntryPoint;  
  
    @Override  
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
        final String authHeader = request.getHeader("Authorization");  
        final String jwt;  
        final String userEmail;  
        log.info("[JWT验证] 进入JWTFilter");  
        // 以下條件為沒有攜帶Token的請求  
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {  
            log.info("[JWT验证] 鉴定为不含Token请求");  
            filterChain.doFilter(request, response);  
            return;  
        }        jwt = authHeader.substring(7);  
        log.info("[JWT验证] 携带Token请求接受到一个" + jwt);  
  
        try {  
            jwtTokenHelper.validateToken(jwt);  
        }catch (SignatureException | MalformedJwtException | UnsupportedJwtException | IllegalArgumentException e) {  
            // 抛出异常,统一让 AuthenticationEntryPoint 处理响应参数  
            authenticationEntryPoint.commence(request, response, new AuthenticationServiceException("Token 不可用"));  
            return;  
        } catch (ExpiredJwtException e) {  
            authenticationEntryPoint.commence(request, response, new AuthenticationServiceException("Token 已失效"));  
            return;  
        }  
        String username = jwtTokenHelper.getUsernameByToken(jwt);  
        if(StringUtils.isNotBlank(username)  && Objects.isNull(SecurityContextHolder.getContext().getAuthentication())) {  
            log.info("[JWT验证] 解析得到username: " + username);  
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);  
  
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(  
                    userDetails, null, userDetails.getAuthorities());  
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));  
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);  
        }  
        filterChain.doFilter(request, response);  
    }}