Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Globalization
Imports Nexamas.UI.Values

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only proof that MASDashboardGrid can retain and restore a large widget
    ''' layout while diagnostics expose only a bounded realized widget window. The gate
    ''' deliberately does not prove child hosting, data refresh, chart engines,
    ''' provider contracts, external storage, or production readiness.
    ''' </summary>
    Friend NotInheritable Class MASDashboardGridLargeLayoutWindowingGate

        Private Sub New()
        End Sub

        Friend Shared Function Passes() As Boolean
            Dim failures As IReadOnlyList(Of String) = Evaluate()
            Return failures.Count = 0
        End Function

        Friend Shared Function Evaluate() As IReadOnlyList(Of String)
            Dim failures As New List(Of String)()

            If Not MASDashboardGridPolicy.HasLargeLayoutWindowingProofPath() Then failures.Add("DashboardGrid large-layout windowing proof path is missing.")

            Dim totalWidgets As Integer = DashboardGridTokens.LargeLayoutProofWidgets
            Dim viewportCapacity As Integer = DashboardGridTokens.MaxVisibleWidgets
            Dim sourceSnapshot As MASDashboardGridLayoutSnapshot = CreateLargeLayoutSnapshot(totalWidgets, BuildWidgetKey(0), 0)
            Dim grid As MASDashboardGrid = MASDashboardGrid.Create("Large Dashboard")
            grid.SetDiagnosticWidgetViewportCapacity(viewportCapacity)

            If Not grid.RestoreLayoutSnapshotForLargeLayoutProof(sourceSnapshot) Then failures.Add("DashboardGrid could not restore the large layout snapshot.")
            If grid.ItemCount <> totalWidgets Then failures.Add("DashboardGrid did not retain the full large-layout widget count.")
            If grid.SelectedWidgetKey <> BuildWidgetKey(0) Then failures.Add("DashboardGrid did not retain the first selected widget after large restore.")
            If grid.GetWidgetKeys().Count <> totalWidgets Then failures.Add("DashboardGrid widget-key count does not match the large layout.")

            Dim firstKey As String = BuildWidgetKey(0)
            Dim firstWindow As MASDashboardGridWidgetWindowSnapshot = grid.CreateWidgetWindowSnapshot()
            If firstWindow.TotalWidgets <> totalWidgets Then failures.Add("Initial widget-window total does not match the large layout.")
            If Not firstWindow.IsBounded Then failures.Add("Initial widget-window realizes more widgets than requested capacity.")
            If firstWindow.RealizedWidgetCount > viewportCapacity Then failures.Add("Initial widget-window exceeds MaxVisibleWidgets.")
            If Not firstWindow.CoversPartialDashboard Then failures.Add("Initial widget-window should cover only a partial dashboard for large layouts.")
            If Not firstWindow.ContainsWidgetKey(firstKey) Then failures.Add("Initial widget-window does not contain the first stable widget key.")
            If grid.GetRealizedWidgetKeys().Count <> firstWindow.RealizedWidgetCount Then failures.Add("Realized widget-key helper does not match the window snapshot.")

            Dim middleIndex As Integer = totalWidgets \ 2
            Dim middleKey As String = BuildWidgetKey(middleIndex)
            If Not grid.EnsureWidgetVisible(middleKey) Then failures.Add("DashboardGrid could not ensure a middle large-layout widget visible.")
            Dim middleWindow As MASDashboardGridWidgetWindowSnapshot = grid.CreateWidgetWindowSnapshot()
            If Not middleWindow.ContainsWidgetKey(middleKey) Then failures.Add("Middle widget was not realized after EnsureWidgetVisible.")
            If Not middleWindow.IsBounded Then failures.Add("Middle widget-window realizes more widgets than requested capacity.")
            If grid.SelectedWidgetKey <> middleKey Then failures.Add("Middle-widget selection was not retained.")

            Dim lastKey As String = BuildWidgetKey(totalWidgets - 1)
            If Not grid.EnsureWidgetVisible(lastKey) Then failures.Add("DashboardGrid could not ensure the final large-layout widget visible.")
            Dim lastWindow As MASDashboardGridWidgetWindowSnapshot = grid.CreateWidgetWindowSnapshot()
            If Not lastWindow.ContainsWidgetKey(lastKey) Then failures.Add("Final widget was not realized in the bounded window.")
            If lastWindow.RealizedWidgetCount > viewportCapacity Then failures.Add("Final widget-window exceeds MaxVisibleWidgets.")
            If lastWindow.FirstWidgetIndex <= 0 Then failures.Add("Final widget-window did not scroll away from the first widget.")
            If grid.SelectedWidgetKey <> lastKey Then failures.Add("Final-widget selection was not retained.")
            If Not grid.HasBoundedWidgetWindow(totalWidgets, viewportCapacity) Then failures.Add("Bounded widget-window helper did not recognize the large-layout proof.")

            If Not grid.MoveWidget(lastKey, 0) Then failures.Add("DashboardGrid could not reorder a large-layout widget.")
            If Not grid.ResizeWidget(lastKey, DashboardGridTokens.MaxSpanColumns, DashboardGridTokens.MaxSpanRows) Then failures.Add("DashboardGrid could not resize a large-layout widget.")
            Dim reorderedSnapshot As MASDashboardGridLayoutSnapshot = grid.CreateLayoutSnapshot()
            If reorderedSnapshot Is Nothing Then failures.Add("DashboardGrid did not create a large reordered snapshot.")
            If reorderedSnapshot IsNot Nothing Then
                If reorderedSnapshot.Widgets.Count <> totalWidgets Then failures.Add("Large reordered snapshot did not retain all widgets.")
                If reorderedSnapshot.Widgets.Count > 0 AndAlso reorderedSnapshot.Widgets(0).Key <> lastKey Then failures.Add("Large reordered snapshot did not persist the moved widget at index 0.")
                If reorderedSnapshot.Widgets.Count > 0 AndAlso reorderedSnapshot.Widgets(0).SpanColumns <> DashboardGridTokens.MaxSpanColumns Then failures.Add("Large reordered snapshot did not persist the resized span columns.")
                If reorderedSnapshot.Widgets.Count > 0 AndAlso reorderedSnapshot.Widgets(0).SpanRows <> DashboardGridTokens.MaxSpanRows Then failures.Add("Large reordered snapshot did not persist the resized span rows.")
                If reorderedSnapshot.SelectedWidgetKey <> lastKey Then failures.Add("Large reordered snapshot did not retain selected widget key.")
            End If

            Dim restored As MASDashboardGrid = MASDashboardGrid.Create("Restored Large Dashboard")
            restored.SetDiagnosticWidgetViewportCapacity(viewportCapacity)
            If reorderedSnapshot Is Nothing OrElse Not restored.RestoreLayoutSnapshotForLargeLayoutProof(reorderedSnapshot) Then failures.Add("DashboardGrid could not restore the reordered large snapshot.")
            If restored.ItemCount <> totalWidgets Then failures.Add("Restored large dashboard did not retain all widgets.")
            If restored.SelectedWidgetKey <> lastKey Then failures.Add("Restored large dashboard did not retain selected widget.")
            Dim restoredWindow As MASDashboardGridWidgetWindowSnapshot = restored.CreateWidgetWindowSnapshot()
            If Not restoredWindow.IsBounded Then failures.Add("Restored large dashboard widget-window is not bounded.")
            If Not restoredWindow.ContainsWidgetKey(lastKey) Then failures.Add("Restored large dashboard window does not contain the selected moved widget.")
            If Not restored.HasLayoutSnapshotForTests() Then failures.Add("Restored large dashboard did not pass layout snapshot self-check.")

            Return failures
        End Function

        Private Shared Function CreateLargeLayoutSnapshot(widgetCount As Integer,
                                                          selectedWidgetKey As String,
                                                          topIndex As Integer) As MASDashboardGridLayoutSnapshot
            Dim widgets As New List(Of MASDashboardGridWidgetSnapshot)(Math.Max(0, widgetCount))
            For index As Integer = 0 To widgetCount - 1
                widgets.Add(New MASDashboardGridWidgetSnapshot(BuildWidgetKey(index),
                                                               "Widget " & index.ToString(CultureInfo.InvariantCulture),
                                                               (index * 10).ToString(CultureInfo.InvariantCulture),
                                                               "Large layout proof",
                                                               1,
                                                               1))
            Next
            Return New MASDashboardGridLayoutSnapshot(1, "Large dashboard proof", selectedWidgetKey, topIndex, widgets)
        End Function

        Private Shared Function BuildWidgetKey(index As Integer) As String
            Return "widget-" & Math.Max(0, index).ToString("0000", CultureInfo.InvariantCulture)
        End Function

    End Class

End Namespace
