using RolemasterDb.App.Features;
using RolemasterDb.App.Frontend.AppState;
using RolemasterDb.App.Frontend.Curation;

namespace RolemasterDb.ImportTool.Tests;

public sealed class CurationQueueResolverTests
{
    [Fact]
    public void Ordered_cells_follow_roll_group_and_column_sort_order()
    {
        var detail = CreateDetail(new CriticalTableCellDetail(4, "21-25", "C", "C", "severity", "B", "Beta", false, null, [], []), new CriticalTableCellDetail(1, "01-05", "B", "B", "severity", null, null, false, null, [], []), new CriticalTableCellDetail(3, "21-25", "A", "A", "severity", null, null, false, null, [], []), new CriticalTableCellDetail(2, "21-25", "B", "B", "severity", "A", "Alpha", false, null, [], []));

        var orderedIds = CurationQueueResolver.GetOrderedCells(detail).Select(cell => cell.ResultId).ToArray();

        Assert.Equal([1, 3, 2, 4], orderedIds);
    }

    [Fact]
    public void Find_first_uncurated_returns_first_matching_cell_in_order()
    {
        var detail = CreateDetail(new CriticalTableCellDetail(1, "01-05", "A", "A", "severity", null, null, true, null, [], []), new CriticalTableCellDetail(2, "01-05", "B", "B", "severity", null, null, false, null, [], []), new CriticalTableCellDetail(3, "06-10", "A", "A", "severity", null, null, false, null, [], []));

        var nextCell = CurationQueueResolver.FindFirstUncurated(detail);

        Assert.NotNull(nextCell);
        Assert.Equal(2, nextCell!.ResultId);
    }

    [Fact]
    public void Find_next_uncurated_advances_without_wrapping()
    {
        var detail = CreateDetail(new CriticalTableCellDetail(1, "01-05", "A", "A", "severity", null, null, false, null, [], []), new CriticalTableCellDetail(2, "01-05", "B", "B", "severity", null, null, true, null, [], []), new CriticalTableCellDetail(3, "06-10", "A", "A", "severity", null, null, false, null, [], []));

        Assert.Equal(3, CurationQueueResolver.FindNextUncurated(detail, 1)!.ResultId);
        Assert.Null(CurationQueueResolver.FindNextUncurated(detail, 3));
    }

    private static CriticalTableDetail CreateDetail(params CriticalTableCellDetail[] cells) =>
        new("slash", "Slash Critical Strike Table", "standard", "Slash.pdf", null, [
            new CriticalColumnReference("A", "A", "severity", 1),
            new CriticalColumnReference("B", "B", "severity", 2),
            new CriticalColumnReference("C", "C", "severity", 3)
        ], [
            new CriticalGroupReference("A", "Alpha", 1),
            new CriticalGroupReference("B", "Beta", 2)
        ], [
            new CriticalRollBandReference("01-05", 1, 5, 1),
            new CriticalRollBandReference("06-10", 6, 10, 2),
            new CriticalRollBandReference("21-25", 21, 25, 3)
        ], cells, []);
}