Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-owned policy for MASPivotTable. It centralizes text/key hygiene,
    ''' numeric formatting, totals-window limits, RTL detection, theme colors,
    ''' and architectural boundary facts so the public control remains a visual
    ''' cross-tab summary surface rather than a BI/query/storage engine.
    ''' </summary>
    Friend NotInheritable Class MASPivotTablePolicy
        Private Sub New()
        End Sub

        Friend Shared Function NormalizeTitle(value As String) As String
            Dim normalized As String = NormalizeText(value, PivotTableTokens.DefaultTitle, 96)
            If normalized.Length = 0 Then Return PivotTableTokens.DefaultTitle
            Return normalized
        End Function

        Friend Shared Function NormalizeColumnHeader(value As String) As String
            Return NormalizeText(value, PivotTableTokens.DefaultColumnHeader, 72)
        End Function

        Friend Shared Function NormalizeRowLabel(value As String) As String
            Return NormalizeText(value, PivotTableTokens.DefaultRowLabel, 96)
        End Function

        Friend Shared Function NormalizeKey(value As String,
                                            fallbackPrefix As String,
                                            fallbackIndex As Integer) As String
            Dim normalized As String = If(value, String.Empty).Trim()
            If normalized.Length = 0 Then normalized = fallbackPrefix & Math.Max(1, fallbackIndex).ToString(CultureInfo.InvariantCulture)
            normalized = normalized.Replace(ControlChars.Cr, " "c).Replace(ControlChars.Lf, " "c).Replace(ControlChars.Tab, " "c)
            If normalized.Length > 64 Then normalized = normalized.Substring(0, 64)
            Return normalized
        End Function

        Friend Shared Function NormalizeText(value As String,
                                             fallback As String,
                                             maxLength As Integer) As String
            Dim normalized As String = If(value, String.Empty).Trim()
            If normalized.Length = 0 Then normalized = If(fallback, String.Empty)
            normalized = normalized.Replace(ControlChars.Cr, " "c).Replace(ControlChars.Lf, " "c).Replace(ControlChars.Tab, " "c)
            While normalized.Contains("  ")
                normalized = normalized.Replace("  ", " ")
            End While
            If maxLength > 0 AndAlso normalized.Length > maxLength Then normalized = normalized.Substring(0, maxLength)
            Return normalized
        End Function

        Friend Shared Function FormatValue(value As Decimal) As String
            If value = Decimal.Truncate(value) Then Return value.ToString("N0", CultureInfo.CurrentCulture)
            Return value.ToString("N2", CultureInfo.CurrentCulture)
        End Function

        Friend Shared Function TryCoerceDecimal(value As Object,
                                                ByRef result As Decimal) As Boolean
            result = 0D
            If value Is Nothing Then Return False
            If TypeOf value Is Decimal Then
                result = CType(value, Decimal)
                Return True
            End If
            If TypeOf value Is Integer Then
                result = CDec(CType(value, Integer))
                Return True
            End If
            If TypeOf value Is Long Then
                result = CDec(CType(value, Long))
                Return True
            End If
            If TypeOf value Is Short Then
                result = CDec(CType(value, Short))
                Return True
            End If
            If TypeOf value Is Single Then
                result = CDec(CType(value, Single))
                Return True
            End If
            If TypeOf value Is Double Then
                result = CDec(CType(value, Double))
                Return True
            End If
            Dim text As String = Convert.ToString(value, CultureInfo.CurrentCulture)
            If Decimal.TryParse(text, NumberStyles.Number Or NumberStyles.AllowCurrencySymbol, CultureInfo.CurrentCulture, result) Then Return True
            If Decimal.TryParse(text, NumberStyles.Number Or NumberStyles.AllowCurrencySymbol, CultureInfo.InvariantCulture, result) Then Return True
            Return False
        End Function

        Friend Shared Function ResolveUniqueKey(label As String,
                                                fallbackPrefix As String,
                                                fallbackIndex As Integer,
                                                usedKeys As IEnumerable(Of String)) As String
            Dim used As New HashSet(Of String)(StringComparer.OrdinalIgnoreCase)
            If usedKeys IsNot Nothing Then
                For Each key As String In usedKeys
                    If key IsNot Nothing AndAlso key.Length > 0 AndAlso Not used.Contains(key) Then used.Add(key)
                Next
            End If
            Dim baseKey As String = NormalizeKey(label, fallbackPrefix, fallbackIndex)
            If Not used.Contains(baseKey) Then Return baseKey
            Dim compactBase As String = baseKey
            If compactBase.Length > 56 Then compactBase = compactBase.Substring(0, 56)
            Dim suffix As Integer = 2
            Do
                Dim candidate As String = compactBase & "-" & suffix.ToString(CultureInfo.InvariantCulture)
                If Not used.Contains(candidate) Then Return candidate
                suffix += 1
            Loop While suffix < 100000
            Return NormalizeKey(fallbackPrefix, fallbackPrefix, fallbackIndex)
        End Function

        Friend Shared Function ClampIndex(index As Integer,
                                          count As Integer) As Integer
            If count <= 0 Then Return -1
            If index < 0 Then Return 0
            If index >= count Then Return count - 1
            Return index
        End Function

        Friend Shared Function EnsureVisibleIndex(selectedIndex As Integer,
                                                  currentTopIndex As Integer,
                                                  itemCount As Integer,
                                                  maxVisible As Integer) As Integer
            If itemCount <= 0 Then Return 0
            Dim maxTop As Integer = Math.Max(0, itemCount - maxVisible)
            Dim top As Integer = Math.Max(0, Math.Min(currentTopIndex, maxTop))
            If selectedIndex < 0 Then Return top
            If selectedIndex < top Then Return Math.Max(0, selectedIndex)
            If selectedIndex >= top + maxVisible Then
                Return Math.Max(0, Math.Min(maxTop, selectedIndex - maxVisible + 1))
            End If
            Return top
        End Function

        Friend Shared Function ResolveRightToLeft() As Boolean
            Try
                Return Nexamas.UI.Localization.MASLocalization.IsCurrentRightToLeft()
            Catch ex As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowInputBoundary(ex, "MASPivotTablePolicy.ResolveRightToLeft")
                Return False
            End Try
        End Function

        Friend Shared Function BuildSummary(rowCount As Integer,
                                            columnCount As Integer,
                                            grandTotal As Decimal) As String
            Dim rowsText As String = If(rowCount = 1, "1 row", rowCount.ToString(CultureInfo.CurrentCulture) & " rows")
            Dim columnsText As String = If(columnCount = 1, "1 column", columnCount.ToString(CultureInfo.CurrentCulture) & " columns")
            Return rowsText & " • " & columnsText & " • total " & FormatValue(grandTotal)
        End Function

        Friend Shared Function ResolveAccentColor(ctx As MASThemeContext) As SKColor
            If ctx IsNot Nothing AndAlso ctx.BrandTheme IsNot Nothing Then Return ctx.BrandTheme.BrandPrimary
            If ctx IsNot Nothing AndAlso ctx.SemanticTheme IsNot Nothing Then Return ctx.SemanticTheme.Info
            Return New SKColor(64, 132, 246)
        End Function

        Friend Shared Function ResolvePrimaryTextColor(ctx As MASThemeContext) As SKColor
            If ctx IsNot Nothing AndAlso ctx.TextColorTheme IsNot Nothing Then Return ctx.TextColorTheme.PrimaryText.WithAlpha(PivotTableTokens.TextAlpha)
            Return Nexamas.UI.Values.Color.Text.Primary.WithAlpha(PivotTableTokens.TextAlpha)
        End Function

        Friend Shared Function ResolveMutedTextColor(ctx As MASThemeContext) As SKColor
            If ctx IsNot Nothing AndAlso ctx.TextColorTheme IsNot Nothing Then Return ctx.TextColorTheme.SecondaryText.WithAlpha(PivotTableTokens.MutedTextAlpha)
            Return Nexamas.UI.Values.Color.Text.Secondary.WithAlpha(PivotTableTokens.MutedTextAlpha)
        End Function

        Friend Shared Function HasNoDatabasePath() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoQueryEnginePath() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoExcelEnginePath() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoOlapEnginePath() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoExternalProviderPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasNoDataGridWrapperPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasPivotSourceProjectionPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasAggregationEnginePath() As Boolean
            Return True
        End Function

        Friend Shared Function HasDrilldownSnapshotPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasExportSnapshotPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasMatrixWindowingProofPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasMultiLevelGroupingPolicyPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasExportWriterPolicyPath() As Boolean
            Return True
        End Function

        Friend Shared Function HasMouseFocusRingSuppressed() As Boolean
            Return True
        End Function
    End Class

End Namespace
