Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only proof that PivotTable owns a deterministic multi-level grouping
    ''' policy by composing row and column hierarchy paths before projection. This
    ''' keeps OLAP/query engines and public source adapters outside the control.
    ''' </summary>
    Friend NotInheritable Class MASPivotTableMultiLevelGroupingGate
        Private Sub New()
        End Sub

        Friend Shared Function Passes() As Boolean
            Try
                If Not MASPivotTablePolicy.HasMultiLevelGroupingPolicyPath() Then Return False

                Dim emeaRetail As MASPivotGroupPath = MASPivotGroupPath.Create("EMEA", "Retail")
                Dim emeaWholesale As MASPivotGroupPath = MASPivotGroupPath.Create("EMEA", "Wholesale")
                Dim y2026Q1 As MASPivotGroupPath = MASPivotGroupPath.Create("2026", "Q1")
                Dim y2026Q2 As MASPivotGroupPath = MASPivotGroupPath.Create("2026", "Q2")

                If emeaRetail.Depth <> 2 OrElse y2026Q1.Depth <> 2 Then Return False
                If Not String.Equals(emeaRetail.DisplayLabel, "EMEA / Retail", StringComparison.Ordinal) Then Return False
                If Not String.Equals(y2026Q1.DisplayLabel, "2026 / Q1", StringComparison.Ordinal) Then Return False

                Dim rows As New List(Of Object) From {
                    MASPivotSourceRecord.Create(emeaRetail.DisplayLabel, y2026Q1.DisplayLabel, 10D, rowField:="rowGroup", columnField:="columnGroup", valueField:="value"),
                    MASPivotSourceRecord.Create(emeaRetail.DisplayLabel, y2026Q1.DisplayLabel, 5D, rowField:="rowGroup", columnField:="columnGroup", valueField:="value"),
                    MASPivotSourceRecord.Create(emeaRetail.DisplayLabel, y2026Q2.DisplayLabel, 20D, rowField:="rowGroup", columnField:="columnGroup", valueField:="value"),
                    MASPivotSourceRecord.Create(emeaWholesale.DisplayLabel, y2026Q1.DisplayLabel, 7D, rowField:="rowGroup", columnField:="columnGroup", valueField:="value")
                }

                Dim source As MASListItemsSource = MASListItemsSource.FromEnumerable(rows, AddressOf ResolveProbeKey)
                Dim definition As MASPivotSourceDefinition = MASPivotSourceDefinition.Create("rowGroup", "columnGroup", "value", MASPivotAggregateKind.Sum)
                Dim pivot As MASPivotTable = MASPivotTable.Create("Multi-level grouping gate")
                pivot.SetPivotSource(source, definition, "MASPivotTableMultiLevelGroupingGate")

                If Not pivot.HasPivotSource Then Return False
                If pivot.RowCount <> 2 OrElse pivot.ColumnCount <> 2 Then Return False
                If pivot.GetCellValue(emeaRetail.DisplayLabel, y2026Q1.DisplayLabel) <> 15D Then Return False
                If pivot.GetRowTotal(emeaRetail.DisplayLabel) <> 35D Then Return False
                If pivot.GetColumnTotal(y2026Q1.DisplayLabel) <> 22D Then Return False
                If pivot.GetCellDrilldown(emeaRetail.DisplayLabel, y2026Q1.DisplayLabel).Count <> 2 Then Return False
                If Not pivot.SelectCell(emeaRetail.DisplayLabel, y2026Q1.DisplayLabel) Then Return False
                If pivot.GetSelectedCellDrilldown().Count <> 2 Then Return False

                Dim snapshot As MASPivotExportSnapshot = pivot.CreatePivotExportSnapshot()
                If snapshot.Rows.Count <> 2 OrElse snapshot.Columns.Count <> 2 Then Return False
                If Not ContainsText(snapshot.Rows, emeaRetail.DisplayLabel) Then Return False
                If Not ContainsText(snapshot.Columns, y2026Q2.DisplayLabel) Then Return False

                Return True
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowDiagnosticOnly(ex, "MASPivotTableMultiLevelGroupingGate")
                Return False
            End Try
        End Function


        Private Shared Function ContainsText(values As IReadOnlyList(Of String),
                                             expected As String) As Boolean
            If values Is Nothing Then Return False
            For Each value As String In values
                If String.Equals(value, expected, StringComparison.Ordinal) Then Return True
            Next
            Return False
        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
            Dim value As Object = Nothing
            record.TryGetField("rowGroup", rowValue)
            record.TryGetField("columnGroup", columnValue)
            record.TryGetField("value", value)
            Return Convert.ToString(rowValue, Globalization.CultureInfo.InvariantCulture) & ":" & Convert.ToString(columnValue, Globalization.CultureInfo.InvariantCulture) & ":" & Convert.ToString(value, Globalization.CultureInfo.InvariantCulture)
        End Function
    End Class

End Namespace
