using System.Security.Cryptography;
using Microsoft.IdentityModel.Tokens;
using OpenWarehouse.auth.lib.Model.WellKnow;

namespace OpenWarehouse.auth.api.Controller;

[ApiController]
public class WellKnown(IConfiguration configuration, ILogger<WellKnown> logger) : ControllerBase
{
    [HttpGet(".well-known/openid-configuration")]
    public ActionResult<OpenIdConfiguration> GetOpenIdConfiguration()
    {
        var issuer = configuration["Jwt:Issuer"] ?? "https://your-oidc-server.com";
        var oidcConfig = new OpenIdConfiguration
        {
            Issuer = issuer,
            AuthorizationEndpoint = $"{issuer}/auth/login",
            TokenEndpoint = $"{issuer}/auth/token",
            JwksUri = $"{issuer}/.well-known/jwks",
            ResponseTypesSupported = new[] { "code", "id_token", "token" },
            SubjectTypesSupported = new[] { "public" },
            IdTokenSigningAlgValuesSupported = new[] { "RS256" }
        };
        
        logger.LogInformation("Served OpenID configuration.");
        return Ok(oidcConfig);
    }
    
    [HttpGet(".well-known/jwks")]
    public ActionResult<JwksResponse> GetJwks()
    {
        var rsaKeyPath = Path.Combine(configuration["contentRoot"] ?? throw new Exception("content root not found"), "private_key_pkcs8.pem");
        
        if (!System.IO.File.Exists(rsaKeyPath))
        {
            logger.LogError("RSA key file not found at path: {Path}", rsaKeyPath);
            return Problem("RSA key not found.", statusCode: 500);
        }

        using var rsa = RSA.Create();
        rsa.ImportFromPem(System.IO.File.ReadAllText(rsaKeyPath));
        
        var parameters = rsa.ExportParameters(false);
        var jwk = new Jwk
        {
            Kty = "RSA",
            E = Base64UrlEncoder.Encode(parameters.Exponent),
            N = Base64UrlEncoder.Encode(parameters.Modulus),
            Use = "sig",
            Alg = "RS256",
            Kid = "1" 
        };

        var jwksResponse = new JwksResponse
        {
            Keys = new[] { jwk }
        };

        logger.LogInformation("JWKS configuration served.");
        return Ok(jwksResponse);
    }
}