using System.ComponentModel;
using System.Globalization;
using SharepointToolbox.Core.Models;
using SharepointToolbox.Services;
using SharepointToolbox.Views.Dialogs;
namespace SharepointToolbox.ViewModels.Dialogs;
///
/// Headless logic for . Loads sites via
/// and applies filter/sort in memory so the
/// dialog's code-behind stays a thin shim and the logic is unit-testable
/// without a WPF host.
///
public class SitePickerDialogLogic
{
private readonly ISiteListService _siteListService;
private readonly TenantProfile _profile;
public SitePickerDialogLogic(ISiteListService siteListService, TenantProfile profile)
{
_siteListService = siteListService;
_profile = profile;
}
///
/// Loads all accessible sites for the tenant profile and wraps them in
/// so the dialog can bind checkboxes.
///
public async Task> LoadAsync(
IProgress progress,
CancellationToken ct)
{
var sites = await _siteListService.GetSitesAsync(_profile, progress, ct);
return sites
.Select(s => new SitePickerItem(s.Url, s.Title, s.StorageUsedMb, s.StorageQuotaMb, s.Template))
.ToList();
}
///
/// Filters items by free-text (title/url substring), storage-size range,
/// and site kind. Empty or zero-range parameters become no-ops.
///
public static IEnumerable ApplyFilter(
IEnumerable items,
string text,
long minMb,
long maxMb,
string kindFilter)
{
var result = items;
if (!string.IsNullOrEmpty(text))
{
result = result.Where(i =>
i.Url.Contains(text, StringComparison.OrdinalIgnoreCase) ||
i.Title.Contains(text, StringComparison.OrdinalIgnoreCase));
}
result = result.Where(i => i.StorageUsedMb >= minMb && i.StorageUsedMb <= maxMb);
if (!string.IsNullOrEmpty(kindFilter) && kindFilter != "All")
result = result.Where(i => i.Kind.ToString() == kindFilter);
return result;
}
///
/// Stable sort by a named column and direction. Unknown column names
/// return the input sequence unchanged.
///
public static IEnumerable ApplySort(
IEnumerable items,
string column,
ListSortDirection direction)
{
var asc = direction == ListSortDirection.Ascending;
return column switch
{
"Title" => asc ? items.OrderBy(i => i.Title) : items.OrderByDescending(i => i.Title),
"Url" => asc ? items.OrderBy(i => i.Url) : items.OrderByDescending(i => i.Url),
"Kind" => asc ? items.OrderBy(i => i.KindDisplay) : items.OrderByDescending(i => i.KindDisplay),
"StorageUsedMb" => asc
? items.OrderBy(i => i.StorageUsedMb)
: items.OrderByDescending(i => i.StorageUsedMb),
"IsSelected" => asc
? items.OrderBy(i => i.IsSelected)
: items.OrderByDescending(i => i.IsSelected),
_ => items
};
}
///
/// Lenient long parse: whitespace-only or unparseable input yields
/// instead of throwing.
///
public static long ParseLongOrDefault(string text, long fallback)
{
if (string.IsNullOrWhiteSpace(text)) return fallback;
return long.TryParse(text.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var v)
? v
: fallback;
}
}