content: package com.alkl1m.taskmanager.util;
  
  import com.alkl1m.taskmanager.entity.User;
  import com.alkl1m.taskmanager.service.auth.UserDetailsImpl;
  import io.jsonwebtoken.*;
  import io.jsonwebtoken.io.Decoders;
  import io.jsonwebtoken.security.Keys;
  import jakarta.servlet.http.Cookie;
  import jakarta.servlet.http.HttpServletRequest;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.http.ResponseCookie;
  import org.springframework.stereotype.Component;
  import org.springframework.web.util.WebUtils;
  import java.security.Key;
  import java.util.Date;
  
  @Component
  public class JwtUtils {
      private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);
      @Value("${application.security.jwt.secret}")
      private String jwtSecret;
      @Value("${application.security.jwt.expirationMs}")
      private int jwtExpirationMs;
      @Value("${application.security.jwt.cookieName}")
      private String jwtCookie;
      @Value("${application.security.jwt.refreshCookieName}")
      private String jwtRefreshCookie;
      public ResponseCookie generateJwtCookie(UserDetailsImpl userPrincipal) {
          String jwt = generateTokenFromEmail(userPrincipal.getEmail());
          return generateCookie(jwtCookie, jwt, "/api");
      }
  
      public ResponseCookie generateJwtCookie(User user) {
          String jwt = generateTokenFromEmail(user.getEmail());
          return generateCookie(jwtCookie, jwt, "/api");
      }
  
      public ResponseCookie generateRefreshJwtCookie(String refreshToken) {
          return generateCookie(jwtRefreshCookie, refreshToken, "/api/auth/refreshToken");
      }
  
      public String getJwtFromCookies(HttpServletRequest request) {
          return getCookieValueByName(request, jwtCookie);
      }
  
      public String getJwtRefreshFromCookies(HttpServletRequest request) {
          return getCookieValueByName(request, jwtRefreshCookie);
      }
  
      public ResponseCookie getCleanJwtCookie() {
          return ResponseCookie.from(jwtCookie, null).path("/api").build();
      }
  
      public ResponseCookie getCleanJwtRefreshToken() {
          return ResponseCookie.from(jwtRefreshCookie, null).path("/api/auth/refreshToken").build();
      }
  
      public String getEmailFromJwtToken(String token) {
          return Jwts.parserBuilder().setSigningKey(key()).build()
                  .parseClaimsJws(token).getBody().getSubject();
      }
  
      private Key key() {
          return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));
      }
  
      public boolean validateJwtToken(String authToken) {
          try {
              Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
              return true;
          } catch (SignatureException e) {
              logger.error("Invalid JWT signature: {}", e.getMessage());
          } catch (MalformedJwtException e) {
              logger.error("Invalid JWT token: {}", e.getMessage());
          } catch (ExpiredJwtException e) {
              logger.error("JWT token is expired: {}", e.getMessage());
          } catch (UnsupportedJwtException e) {
              logger.error("JWT token is unsupported: {}", e.getMessage());
          } catch (IllegalArgumentException e) {
              logger.error("JWT claims string is empty: {}", e.getMessage());
          }
  
          return false;
      }
  
      public String generateTokenFromEmail(String email) {
          return Jwts.builder()
                  .setSubject(email)
                  .setIssuedAt(new Date())
                  .setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
                  .signWith(key(), SignatureAlgorithm.HS256)
                  .compact();
      }
  
      private ResponseCookie generateCookie(String name, String value, String path) {
          return ResponseCookie.from(name, value).path(path).maxAge(24 * 60 * 60).httpOnly(true).build();
      }
  
      private String getCookieValueByName(HttpServletRequest request, String name) {
          Cookie cookie = WebUtils.getCookie(request, name);
          if (cookie != null) {
              return cookie.getValue();
          } else {
              return null;
          }
      }
  }
  