package com.codebyte.api.auth.security;

import com.codebyte.api.auth.domain.User;
import com.codebyte.api.config.AppProperties;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
import org.springframework.security.oauth2.jwt.JwsHeader;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;
import org.springframework.stereotype.Component;

/** Issues signed access tokens (HS256 JWT) for authenticated users. */
@Component
public class JwtService {

    private final JwtEncoder jwtEncoder;
    private final AppProperties properties;

    public JwtService(JwtEncoder jwtEncoder, AppProperties properties) {
        this.jwtEncoder = jwtEncoder;
        this.properties = properties;
    }

    /** Returns a compact, signed access token for the user. */
    public String issueAccessToken(User user) {
        Instant now = Instant.now();
        JwtClaimsSet claims =
                JwtClaimsSet.builder()
                        .issuer(properties.jwt().issuer())
                        .audience(List.of(properties.jwt().audience()))
                        .subject(user.getId().toString())
                        .issuedAt(now)
                        .expiresAt(now.plus(properties.jwt().accessTtl()))
                        .id(UUID.randomUUID().toString())
                        .claim("email", user.getEmail())
                        .claim("roles", user.getRoles())
                        .build();
        JwsHeader header = JwsHeader.with(MacAlgorithm.HS256).build();
        return jwtEncoder.encode(JwtEncoderParameters.from(header, claims)).getTokenValue();
    }

    public long accessTokenTtlSeconds() {
        return properties.jwt().accessTtl().toSeconds();
    }
}
