package com.project.whatsappchatbot.security.jwt;

import com.project.whatsappchatbot.security.services.UserDetailsImpl;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.InputStream;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;

import static com.project.whatsappchatbot.security.jwt.RsaKeyUtil.getPublicKey;

@Component
public class JwtUtils {
	private static final Logger logger = LoggerFactory.getLogger(JwtUtils.class);

	@Autowired
	private JwtBlacklist jwtBlacklist;

	@Value("${bikefixup.app.jwtSecret}")
	private String jwtSecret;
	
	@Value("${bikefixup.app.jwtExpirationMs}")
	private int jwtExpirationMs;

    private String privateKeyPath;

    private String publicKeyPath;
	
	
	private final PrivateKey privateKey;
	private final PublicKey publicKey;

//	public JwtUtils() throws Exception {
//		this.privateKey = RsaKeyUtil.getPrivateKey("src/main/resources/keys/private.pem");
//		this.publicKey = getPublicKey("src/main/resources/keys/public.pem");
//	}
	
	@Autowired
	public JwtUtils(@Value("${jwt.private-key-path}") String privateKeyPath, @Value("${jwt.public-key-path}") String publicKeyPath) throws Exception {
		
	    try (InputStream privateKeyStream = new FileInputStream(privateKeyPath);
	         InputStream publicKeyStream = new FileInputStream(publicKeyPath)) {

	        if (privateKeyStream == null || publicKeyStream == null) {
	            throw new IllegalStateException("Key files not found " + privateKeyPath + " or " + publicKeyPath);
	        }

	        this.privateKey = RsaKeyUtil.getPrivateKey(privateKeyStream);
	        this.publicKey = RsaKeyUtil.getPublicKey(publicKeyStream);
	    }
	}


	public String generateJwtToken(Authentication authentication) {

		UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();

		return Jwts.builder()
				.setSubject((userPrincipal.getUsername()))
				.setIssuedAt(new Date())
				.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
//				.signWith(SignatureAlgorithm.HS512, jwtSecret)
				.signWith(SignatureAlgorithm.RS256, privateKey)
				.compact();
	}
//
	public String generateJwtTokenForApp(UserDetails userDetails) {

//		UserDetailsImpl userPrincipal = (UserDetailsImpl) authentication.getPrincipal();

		return Jwts.builder().setSubject((userDetails.getUsername())).setIssuedAt(new Date())
				.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
				.signWith(privateKey, SignatureAlgorithm.RS256).compact();
//				.signWith(SignatureAlgorithm.HS512, jwtSecret).compact();
	}

	public String getUserNameFromJwtToken(String token) {
		return  Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token).getBody().getSubject();
	}
//
//	public boolean validateJwtToken(String authToken) {
//		try {
//
//			if (jwtBlacklist.isTokenBlacklisted(authToken)) {
//				return false;
//			}
//
//			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 generateJwtToken(String username) {
        return Jwts.builder()
                .setSubject(username)
//                .setIssuer("my-app")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 3600_000)) // 1 hour
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    public Claims validateJwtToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(publicKey)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
    
    public String generateJwtTokeWithPhone(String phone) {
        return Jwts.builder()
                .setSubject(phone)
//                .setIssuer("my-app")
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + 60000)) // 5 minute
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }
}
