package com.zl.mjga.config.security;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Getter
public class Jwt {

  private final String secret;

  private final int expirationMin;

  private final JWTVerifier verifier;

  public Jwt(
      @Value("${jwt.secret}") String secret, @Value("${jwt.expiration-min}") int expirationMin) {
    this.verifier = JWT.require(Algorithm.HMAC256(secret)).build();
    this.secret = secret;
    this.expirationMin = expirationMin;
  }

  public String getSubject(String token) {
    return JWT.decode(token).getSubject();
  }

  public Boolean verify(String token) {
    try {
      verifier.verify(token);
      return Boolean.TRUE;
    } catch (JWTVerificationException e) {
      return Boolean.FALSE;
    }
  }

  public String extract(HttpServletRequest request) {
    String authorization = request.getHeader("Authorization");
    if (StringUtils.isNotEmpty(authorization) && authorization.startsWith("Bearer")) {
      return authorization.substring(7);
    } else {
      return null;
    }
  }

  public String create(String userIdentify) {
    return JWT.create()
        .withSubject(String.valueOf(userIdentify))
        .withIssuedAt(new Date())
        .withExpiresAt(
            Date.from(
                LocalDateTime.now()
                    .plusMinutes(expirationMin)
                    .atZone(ZoneId.systemDefault())
                    .toInstant()))
        .sign(Algorithm.HMAC256(secret));
  }

  public void makeToken(
      HttpServletRequest request, HttpServletResponse response, String userIdentify) {
    response.addHeader("Authorization", String.format("Bearer %s", create(userIdentify)));
  }

  public void removeToken(HttpServletRequest request, HttpServletResponse response) {
    response.addHeader("Authorization", null);
  }
}
