using System.Linq;
using System.Security.Claims;
using System.IdentityModel.Tokens.Jwt;
using AS400API.Auth;
using AS400API.Configuration;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace AS400API.Endpoints;

public static class AuthEndpoints
{
    public static RouteGroupBuilder MapAuthEndpoints(this RouteGroupBuilder group)
    {
        group.MapPost("/v1/auth/login", async Task<IResult> (LoginRequest request, DemoUserStore userStore, TokenService tokenService, JwtOptions jwtOptions) =>
        {
            if (request is null || string.IsNullOrWhiteSpace(request.Username) || string.IsNullOrWhiteSpace(request.Password))
            {
                return Results.BadRequest(new { error = "Username and password are required." });
            }

            var user = await userStore.FindByNameAsync(request.Username);
            if (user is null || !userStore.ValidateCredentials(user, request.Password))
            {
                return Results.Unauthorized();
            }

            var accessToken = tokenService.CreateToken(user);
            return Results.Ok(new LoginResponse(accessToken, jwtOptions.AccessTokenLifetimeMinutes * 60, "Bearer", user.Roles));
        })
        .AllowAnonymous()
        .WithSummary("Exchange credentials for a JWT access token")
        .Produces<LoginResponse>(StatusCodes.Status200OK)
        .Produces(StatusCodes.Status400BadRequest)
        .Produces(StatusCodes.Status401Unauthorized);

        group.MapGet("/v1/users/me", (ClaimsPrincipal user) =>
        {
            var username = user.Identity?.Name ?? user.FindFirstValue(JwtRegisteredClaimNames.Sub) ?? "unknown";
            var roles = user.FindAll(ClaimTypes.Role).Select(r => r.Value).ToArray();
            return Results.Ok(new { username, roles });
        })
        .RequireAuthorization()
        .WithSummary("Returns the current user's profile from the access token");

        return group;
    }
}
