using Microsoft.AspNetCore.Mvc;

namespace SportsDivision.Web.Helpers;

public static class PaginationHelper
{
    public const int PageSize = 20;

    /// <summary>Page-size choices offered in the UI. 0 means "All".</summary>
    public static readonly int[] PageSizeOptions = { 20, 50, 100, 500, 0 };

    /// <summary>
    /// Slices <paramref name="source"/> to the requested page and records paging
    /// metadata in ViewData (read as ViewBag.Page / ViewBag.TotalPages / ViewBag.PageSize
    /// in views). A <paramref name="pageSize"/> of 0 (or less) means "show all".
    /// </summary>
    public static List<T> Page<T>(this Controller controller, IEnumerable<T> source, int page, int pageSize = PageSize)
    {
        var list = source as IList<T> ?? source.ToList();

        // Only the offered choices are honoured; anything else falls back to the default.
        if (!PageSizeOptions.Contains(pageSize)) pageSize = PageSize;
        var showAll = pageSize <= 0;

        var totalPages = showAll ? 1 : (int)Math.Ceiling(list.Count / (double)pageSize);
        if (page < 1) page = 1;
        if (totalPages > 0 && page > totalPages) page = totalPages;

        controller.ViewData["Page"] = page;
        controller.ViewData["TotalPages"] = totalPages;
        controller.ViewData["TotalItems"] = list.Count;
        controller.ViewData["PageSize"] = pageSize; // 0 == All

        if (showAll) return list.ToList();
        return list.Skip((page - 1) * pageSize).Take(pageSize).ToList();
    }
}
