using Microsoft.SharePoint.Client;
using SharepointToolbox.Core.Models;

namespace SharepointToolbox.Services;

/// <summary>
/// Resolves SharePoint group names to their transitive member lists via CSOM + Microsoft Graph.
/// Used as a pre-render step in HTML report export (Phase 17).
/// </summary>
public interface ISharePointGroupResolver
{
    /// <summary>
    /// Resolves the given SharePoint group names to their transitive leaf-user members.
    ///
    /// For each group name:
    ///   - CSOM loads the direct members from <see cref="Microsoft.SharePoint.Client.GroupCollection"/>.
    ///   - Any members that are nested AAD groups (login prefix <c>c:0t.c|tenant|</c>) are expanded
    ///     transitively via the Microsoft Graph <c>groups/{id}/transitiveMembers/microsoft.graph.user</c> endpoint.
    ///   - Members are de-duplicated by login (OrdinalIgnoreCase).
    ///
    /// Failures (throttling, group not found, Graph errors) are handled gracefully:
    /// the group entry is included in the result with an empty member list rather than throwing.
    /// </summary>
    /// <param name="ctx">SharePoint ClientContext for CSOM group member loading.</param>
    /// <param name="clientId">App registration client ID used by <see cref="SharepointToolbox.Infrastructure.Auth.GraphClientFactory"/>.</param>
    /// <param name="groupNames">List of SharePoint group display names to resolve.</param>
    /// <param name="ct">Cancellation token.</param>
    /// <returns>
    /// A read-only dictionary keyed by group name (OrdinalIgnoreCase) mapping to the list of resolved members.
    /// Never throws — a group with a resolution failure maps to an empty list.
    /// </returns>
    Task<IReadOnlyDictionary<string, IReadOnlyList<ResolvedMember>>> ResolveGroupsAsync(
        ClientContext ctx,
        string clientId,
        IReadOnlyList<string> groupNames,
        CancellationToken ct);
}
