using GameList.Contracts;

namespace GameList.Endpoints;

internal static class AuthValidator
{
    public const int MaxUsernameLength = 24;
    public const int MaxDisplayNameLength = 16;
    public const int MaxAdminKeyLength = 128;

    public static bool TryValidateRegistration(RegisterRequest request, out ValidatedRegistration validated, out string error)
    {
        var username = (request.Username ?? string.Empty).Trim();
        if (string.IsNullOrWhiteSpace(username) || username.Length > MaxUsernameLength)
        {
            validated = default;
            error = $"Username is required and must be <= {MaxUsernameLength} characters.";
            return false;
        }

        if (string.IsNullOrWhiteSpace(request.Password))
        {
            validated = default;
            error = "Password is required.";
            return false;
        }

        if ((request.DisplayName ?? string.Empty).Trim().Length > MaxDisplayNameLength)
        {
            validated = default;
            error = $"Display name must be <= {MaxDisplayNameLength} characters.";
            return false;
        }

        var displayName = EndpointHelpers.TrimTo(request.DisplayName, MaxDisplayNameLength);
        if (string.IsNullOrWhiteSpace(displayName))
        {
            validated = default;
            error = "Display name is required.";
            return false;
        }

        var adminKey = EndpointHelpers.TrimTo(request.AdminKey, MaxAdminKeyLength);
        validated = new ValidatedRegistration(username, username.ToLowerInvariant(), displayName, adminKey);
        error = string.Empty;
        return true;
    }

    public static bool TryValidateLogin(LoginRequest request, out string username, out string normalizedUsername, out string error)
    {
        username = (request.Username ?? string.Empty).Trim();
        normalizedUsername = string.Empty;

        if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(request.Password))
        {
            error = "Username and password are required.";
            return false;
        }

        if (username.Length > MaxUsernameLength)
        {
            error = $"Username must be <= {MaxUsernameLength} characters.";
            return false;
        }

        normalizedUsername = username.ToLowerInvariant();
        error = string.Empty;
        return true;
    }

    public readonly record struct ValidatedRegistration(
        string Username,
        string NormalizedUsername,
        string DisplayName,
        string? AdminKey
    );
}
