using Bunit;
using Microsoft.AspNetCore.Components;
using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Shared;

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

/// <summary>
/// Regression tests for CentralUI-016. <c>DataTable</c> looped
/// <c>for i = 1..totalPages</c> and emitted one numbered <c>&lt;li&gt;</c>
/// button per page; a few thousand records at page size 25 rendered hundreds
/// of buttons into the diff on every state change. The fix windows the pager
/// so only first / last / a small range around the current page render.
/// </summary>
public class DataTablePagerTests : BunitContext
{
    private IRenderedComponent<DataTable<int>> RenderTable(int itemCount, int pageSize = 25)
    {
        return Render<DataTable<int>>(parameters => parameters
            .Add(p => p.Items, Enumerable.Range(1, itemCount).ToList())
            .Add(p => p.PageSize, pageSize)
            .Add(p => p.ShowSearch, false)
            .Add(p => p.HeaderContent, (RenderFragment)(b => b.AddMarkupContent(0, "<th>N</th>")))
            .Add(p => p.RowContent, (RenderFragment<int>)(item => b => b.AddMarkupContent(0, $"<tr><td>{item}</td></tr>"))));
    }

    private static int NumberedPageButtons(IRenderedComponent<DataTable<int>> cut)
        => cut.FindAll("ul.pagination li.page-item button")
              .Count(b => int.TryParse(b.TextContent.Trim(), out _));

    [Fact]
    public void Pager_WithThousandsOfPages_RendersWindowedNotEveryPage()
    {
        // 5000 items / 25 = 200 pages. The pre-fix pager rendered 200 numbered
        // buttons; the windowed pager renders at most a dozen.
        var cut = RenderTable(itemCount: 5000);

        var numbered = NumberedPageButtons(cut);

        Assert.True(numbered <= 12,
            $"Expected a windowed pager (<= 12 numbered buttons) but rendered {numbered}.");
    }

    [Fact]
    public void Pager_SmallDataset_StillRendersEveryPage()
    {
        // 5 pages — small enough to render all numbered buttons (no windowing harm).
        var cut = RenderTable(itemCount: 125);

        var numbered = NumberedPageButtons(cut);

        Assert.Equal(5, numbered);
    }

    [Fact]
    public void Pager_WindowedAroundCurrentPage_AlwaysIncludesFirstAndLast()
    {
        var cut = RenderTable(itemCount: 5000); // 200 pages

        var numbered = cut.FindAll("ul.pagination li.page-item button")
            .Select(b => b.TextContent.Trim())
            .Where(t => int.TryParse(t, out _))
            .ToList();

        // First and last page are always reachable from the windowed pager.
        Assert.Contains("1", numbered);
        Assert.Contains("200", numbered);
    }
}
