using SharepointToolbox.Infrastructure.Auth;

namespace SharepointToolbox.Services;

/// <summary>
/// Searches tenant users via Microsoft Graph API.
/// Used by the people-picker autocomplete in the User Access Audit tab.
/// </summary>
public class GraphUserSearchService : IGraphUserSearchService
{
    private readonly GraphClientFactory _graphClientFactory;

    public GraphUserSearchService(GraphClientFactory graphClientFactory)
    {
        _graphClientFactory = graphClientFactory;
    }

    public async Task<IReadOnlyList<GraphUserResult>> SearchUsersAsync(
        string clientId,
        string query,
        int maxResults = 10,
        CancellationToken ct = default)
    {
        if (string.IsNullOrWhiteSpace(query) || query.Length < 2)
            return Array.Empty<GraphUserResult>();

        var graphClient = await _graphClientFactory.CreateClientAsync(clientId, ct);

        // Use $filter with startsWith on displayName and mail.
        // Graph API requires ConsistencyLevel=eventual for advanced queries.
        var escapedQuery = query.Replace("'", "''");
        var response = await graphClient.Users.GetAsync(config =>
        {
            config.QueryParameters.Filter =
                $"startsWith(displayName,'{escapedQuery}') or startsWith(mail,'{escapedQuery}') or startsWith(userPrincipalName,'{escapedQuery}')";
            config.QueryParameters.Select = new[] { "displayName", "userPrincipalName", "mail" };
            config.QueryParameters.Top = maxResults;
            config.QueryParameters.Orderby = new[] { "displayName" };
            config.Headers.Add("ConsistencyLevel", "eventual");
            config.QueryParameters.Count = true;
        }, ct);

        if (response?.Value is null)
            return Array.Empty<GraphUserResult>();

        return response.Value
            .Select(u => new GraphUserResult(
                DisplayName: u.DisplayName ?? u.UserPrincipalName ?? "Unknown",
                UserPrincipalName: u.UserPrincipalName ?? string.Empty,
                Mail: u.Mail))
            .ToList();
    }
}
