using SharepointToolbox.Core.Models;

namespace SharepointToolbox.Core.Helpers;

/// <summary>
/// Merges a flat list of UserAccessEntry rows into consolidated entries
/// where rows with identical (UserLogin, PermissionLevel, AccessType, GrantedThrough)
/// are grouped into a single row with multiple locations.
/// </summary>
public static class PermissionConsolidator
{
    /// <summary>
    /// Builds a pipe-delimited, case-insensitive composite key from the four key fields.
    /// </summary>
    internal static string MakeKey(UserAccessEntry entry)
    {
        return string.Join("|",
            entry.UserLogin.ToLowerInvariant(),
            entry.PermissionLevel.ToLowerInvariant(),
            entry.AccessType.ToString(),
            entry.GrantedThrough.ToLowerInvariant());
    }

    /// <summary>
    /// Groups entries by composite key and returns consolidated rows.
    /// Each group's first entry provides UserDisplayName, IsHighPrivilege, IsExternalUser.
    /// All entries in a group contribute a LocationInfo to the Locations list.
    /// Results are ordered by UserLogin then PermissionLevel.
    /// </summary>
    public static IReadOnlyList<ConsolidatedPermissionEntry> Consolidate(
        IReadOnlyList<UserAccessEntry> entries)
    {
        if (entries.Count == 0)
            return Array.Empty<ConsolidatedPermissionEntry>();

        return entries
            .GroupBy(e => MakeKey(e))
            .Select(g =>
            {
                var first = g.First();
                var locations = g.Select(e => new LocationInfo(
                    e.SiteUrl, e.SiteTitle, e.ObjectTitle, e.ObjectUrl, e.ObjectType
                )).ToList();

                return new ConsolidatedPermissionEntry(
                    first.UserDisplayName,
                    first.UserLogin,
                    first.PermissionLevel,
                    first.AccessType,
                    first.GrantedThrough,
                    first.IsHighPrivilege,
                    first.IsExternalUser,
                    locations,
                    first.TargetUrl,
                    first.TargetLabel,
                    first.SharingLinkType);
            })
            .OrderBy(c => c.UserLogin)
            .ThenBy(c => c.PermissionLevel)
            .ToList();
    }
}
