Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only proof that MASPivotTable can retain a large pivot matrix projection
    ''' while diagnostics for rendering/input expose only a bounded row/column cell
    ''' window. The gate avoids timing assertions and does not call export snapshot so
    ''' it does not prove full export performance or production readiness.
    ''' </summary>
    Friend NotInheritable Class MASPivotTableMatrixWindowingGate

        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 MASPivotTablePolicy.HasMatrixWindowingProofPath() Then failures.Add("Pivot matrix-windowing proof path is missing.")

            Dim rowCount As Integer = PivotTableTokens.LargeMatrixProofRows
            Dim columnCount As Integer = PivotTableTokens.LargeMatrixProofColumns
            Dim totalCells As Integer = PivotTableTokens.LargeMatrixProofCells
            Dim records As New List(Of Object)(totalCells)

            For rowIndex As Integer = 0 To rowCount - 1
                Dim rowKey As String = BuildRowKey(rowIndex)
                For columnIndex As Integer = 0 To columnCount - 1
                    Dim columnKey As String = BuildColumnKey(columnIndex)
                    records.Add(MASPivotSourceRecord.Create(rowKey, columnKey, 1D))
                Next
            Next

            Dim source As MASListItemsSource = MASListItemsSource.FromEnumerable(records, AddressOf ResolveProbeKey)
            Dim definition As MASPivotSourceDefinition = MASPivotSourceDefinition.Create("row", "column", "value", MASPivotAggregateKind.Sum)
            Dim pivot As MASPivotTable = MASPivotTable.Create("Large Pivot Matrix")
            pivot.SetDiagnosticRowViewportCapacity(PivotTableTokens.MaxVisibleRows)
            pivot.SetDiagnosticColumnViewportCapacity(PivotTableTokens.MaxVisibleColumns)
            pivot.SetPivotSource(source, definition, "MASPivotTableMatrixWindowingGate")

            If Not pivot.HasPivotSource Then failures.Add("PivotTable did not retain the large source link.")
            If pivot.PivotProjectionRevision < 0 Then failures.Add("Pivot source revision was not captured.")
            If pivot.RowCount <> rowCount Then failures.Add("PivotTable did not retain the full large-matrix row count.")
            If pivot.ColumnCount <> columnCount Then failures.Add("PivotTable did not retain the full large-matrix column count.")
            If pivot.GetCellValue(BuildRowKey(0), BuildColumnKey(0)) <> 1D Then failures.Add("First projected cell value is incorrect.")
            If pivot.GetCellValue(BuildRowKey(rowCount - 1), BuildColumnKey(columnCount - 1)) <> 1D Then failures.Add("Final projected cell value is incorrect.")
            If pivot.GetRowTotal(BuildRowKey(0)) <> CDec(columnCount) Then failures.Add("First row total is incorrect for the large matrix.")
            If pivot.GetColumnTotal(BuildColumnKey(0)) <> CDec(rowCount) Then failures.Add("First column total is incorrect for the large matrix.")
            If pivot.GrandTotal <> CDec(totalCells) Then failures.Add("Grand total is incorrect for the large matrix.")

            Dim firstRowKey As String = BuildRowKey(0)
            Dim firstColumnKey As String = BuildColumnKey(0)
            Dim firstWindow As MASPivotMatrixWindowSnapshot = pivot.CreateMatrixWindowSnapshot()
            If firstWindow.TotalRows <> rowCount Then failures.Add("Initial matrix-window row total does not match the large matrix.")
            If firstWindow.TotalColumns <> columnCount Then failures.Add("Initial matrix-window column total does not match the large matrix.")
            If firstWindow.TotalCellCount <> CLng(totalCells) Then failures.Add("Initial matrix-window cell total does not match the large matrix.")
            If Not firstWindow.IsBounded Then failures.Add("Initial matrix-window realizes more cells than requested capacity.")
            If firstWindow.RealizedRowCount > PivotTableTokens.MaxVisibleRows Then failures.Add("Initial matrix-window exceeds MaxVisibleRows.")
            If firstWindow.RealizedColumnCount > PivotTableTokens.MaxVisibleColumns Then failures.Add("Initial matrix-window exceeds MaxVisibleColumns.")
            If firstWindow.RealizedCellCount > PivotTableTokens.MaxVisibleRows * PivotTableTokens.MaxVisibleColumns Then failures.Add("Initial matrix-window exceeds bounded cell capacity.")
            If Not firstWindow.CoversPartialMatrix Then failures.Add("Initial matrix-window should cover only a partial matrix for large sources.")
            If Not firstWindow.ContainsCell(firstRowKey, firstColumnKey) Then failures.Add("Initial matrix-window does not contain the first stable cell coordinate.")
            If pivot.GetRealizedCellKeys().Count <> firstWindow.RealizedCellCount Then failures.Add("Realized cell-key helper does not match the window snapshot.")

            Dim middleRow As Integer = rowCount \ 2
            Dim middleColumn As Integer = columnCount \ 2
            Dim middleRowKey As String = BuildRowKey(middleRow)
            Dim middleColumnKey As String = BuildColumnKey(middleColumn)
            If Not pivot.EnsureCellVisible(middleRowKey, middleColumnKey) Then failures.Add("PivotTable could not ensure a middle large-matrix cell visible.")
            Dim middleWindow As MASPivotMatrixWindowSnapshot = pivot.CreateMatrixWindowSnapshot()
            If Not middleWindow.ContainsCell(middleRowKey, middleColumnKey) Then failures.Add("Middle cell was not realized after EnsureCellVisible.")
            If Not middleWindow.IsBounded Then failures.Add("Middle matrix-window realizes more cells than requested capacity.")
            If pivot.SelectedRowKey <> middleRowKey OrElse pivot.SelectedColumnKey <> middleColumnKey Then failures.Add("Middle-cell selection was not retained.")

            Dim lastRowKey As String = BuildRowKey(rowCount - 1)
            Dim lastColumnKey As String = BuildColumnKey(columnCount - 1)
            If Not pivot.EnsureCellVisible(lastRowKey, lastColumnKey) Then failures.Add("PivotTable could not ensure the final large-matrix cell visible.")
            Dim lastWindow As MASPivotMatrixWindowSnapshot = pivot.CreateMatrixWindowSnapshot()
            If Not lastWindow.ContainsCell(lastRowKey, lastColumnKey) Then failures.Add("Final cell was not realized in the bounded window.")
            If lastWindow.RealizedRowCount > PivotTableTokens.MaxVisibleRows Then failures.Add("Final matrix-window exceeds MaxVisibleRows.")
            If lastWindow.RealizedColumnCount > PivotTableTokens.MaxVisibleColumns Then failures.Add("Final matrix-window exceeds MaxVisibleColumns.")
            If lastWindow.RealizedCellCount > PivotTableTokens.MaxVisibleRows * PivotTableTokens.MaxVisibleColumns Then failures.Add("Final matrix-window exceeds bounded cell capacity.")
            If lastWindow.FirstRowIndex <= 0 Then failures.Add("Final matrix-window did not scroll away from the first row.")
            If lastWindow.FirstColumnIndex <= 0 Then failures.Add("Final matrix-window did not scroll away from the first column.")
            If pivot.SelectedRowKey <> lastRowKey OrElse pivot.SelectedColumnKey <> lastColumnKey Then failures.Add("Final-cell selection was not retained.")
            If pivot.PivotProjectionRevision <> lastWindow.ProjectionRevision Then failures.Add("Window snapshot projection revision does not match the PivotTable source revision.")

            If Not pivot.HasBoundedMatrixWindow(totalCells, PivotTableTokens.MaxVisibleRows, PivotTableTokens.MaxVisibleColumns) Then failures.Add("Bounded matrix-window helper did not recognize the large-matrix proof.")

            Return failures
        End Function

        Private Shared Function BuildRowKey(rowIndex As Integer) As String
            Return "row-" & rowIndex.ToString(System.Globalization.CultureInfo.InvariantCulture)
        End Function

        Private Shared Function BuildColumnKey(columnIndex As Integer) As String
            Return "column-" & columnIndex.ToString(System.Globalization.CultureInfo.InvariantCulture)
        End Function

        Private Shared Function ResolveProbeKey(item As Object) As String
            Dim record As MASPivotSourceRecord = TryCast(item, MASPivotSourceRecord)
            If record Is Nothing Then Return String.Empty
            Dim rowValue As Object = Nothing
            Dim columnValue As Object = Nothing
            record.TryGetField("row", rowValue)
            record.TryGetField("column", columnValue)
            Return Convert.ToString(rowValue, Globalization.CultureInfo.InvariantCulture) & ":" & Convert.ToString(columnValue, Globalization.CultureInfo.InvariantCulture)
        End Function

    End Class

End Namespace
