namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;

/// <summary>
/// Pure helper for windowed pagination. Computes the set of
/// page numbers a pager should render: always the first and last page plus a
/// small range around the current page, with the rest elided. Keeps the
/// rendered button count bounded regardless of the total page count, instead
/// of emitting one <c>&lt;li&gt;</c> per page.
/// </summary>
public static class PagerWindow
{
    /// <summary>
    /// Returns the page numbers to render. A value of <c>0</c> in the result is
    /// an ellipsis placeholder (a gap between non-contiguous page numbers).
    /// <paramref name="radius"/> is how many pages to show on each side of the
    /// current page.
    /// </summary>
    /// <param name="currentPage">The currently active page (1-based).</param>
    /// <param name="totalPages">The total number of pages.</param>
    /// <param name="radius">Number of page buttons to show on each side of the current page; default 2.</param>
    /// <returns>An ordered list of page numbers and <c>0</c> ellipsis placeholders.</returns>
    public static IReadOnlyList<int> Build(int currentPage, int totalPages, int radius = 2)
    {
        if (totalPages <= 1)
        {
            return totalPages == 1 ? new[] { 1 } : Array.Empty<int>();
        }

        currentPage = Math.Clamp(currentPage, 1, totalPages);

        // Small enough that windowing buys nothing — render every page.
        var maxUnwindowed = 2 * radius + 5;
        if (totalPages <= maxUnwindowed)
        {
            return Enumerable.Range(1, totalPages).ToList();
        }

        var pages = new SortedSet<int> { 1, totalPages };
        for (var p = currentPage - radius; p <= currentPage + radius; p++)
        {
            if (p >= 1 && p <= totalPages)
            {
                pages.Add(p);
            }
        }

        // Walk the sorted set, inserting an ellipsis (0) wherever a gap exists.
        var result = new List<int>();
        var previous = 0;
        foreach (var page in pages)
        {
            if (previous != 0 && page - previous > 1)
            {
                result.Add(0); // ellipsis
            }
            result.Add(page);
            previous = page;
        }
        return result;
    }
}
