Option Strict On
Option Explicit On

Imports System
Imports System.Globalization
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-owned policy for MASDashboardGrid. It centralizes text/key hygiene,
    ''' selection bounds, span normalization, RTL detection, theme color resolution,
    ''' and explicit boundaries. It deliberately does not own data refresh, metric
    ''' collection, chart engines, responsive shell layout, storage, or providers.
    ''' </summary>
    Friend NotInheritable Class MASDashboardGridPolicy
        Private Sub New()
        End Sub

        Friend Shared Function NormalizeTitle(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return DashboardGridTokens.DefaultTitle
            Return ClampText(text, 64)
        End Function

        Friend Shared Function NormalizeWidgetTitle(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return DashboardGridTokens.DefaultWidgetTitle
            Return ClampText(text, 72)
        End Function

        Friend Shared Function NormalizeValue(value As String) As String
            Return ClampText(NormalizeText(value), 48)
        End Function

        Friend Shared Function NormalizeCaption(value As String) As String
            Return ClampText(NormalizeText(value), 96)
        End Function

        Friend Shared Function NormalizeKey(value As String,
                                            fallbackPrefix As String,
                                            ordinal As Integer) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then text = fallbackPrefix & Math.Max(1, ordinal).ToString(CultureInfo.InvariantCulture)
            text = text.Replace(" "c, "-"c)
            Return ClampText(text, 64)
        End Function

        Friend Shared Function NormalizeText(value As String) As String
            If value Is Nothing Then Return String.Empty
            Dim text As String = value.Trim()
            If text.Length = 0 Then Return String.Empty
            Do While text.Contains("  ")
                text = text.Replace("  ", " ")
            Loop
            Return text
        End Function

        Friend Shared Function ClampText(value As String,
                                         maxLength As Integer) As String
            Dim text As String = If(value, String.Empty)
            If maxLength <= 0 OrElse text.Length <= maxLength Then Return text
            Return text.Substring(0, Math.Max(0, maxLength - 1)) & "…"
        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 ClampSpan(value As Integer,
                                          maxValue As Integer) As Integer
            If value < 1 Then Return 1
            If value > maxValue Then Return maxValue
            Return value
        End Function

        Friend Shared Function ResolveColumnCount(widthPx As Single,
                                                  dpi As Single) As Integer
            Dim safeDpi As Single = If(dpi <= 0.01F, 1.0F, dpi)
            Dim dipWidth As Single = widthPx / safeDpi
            Dim estimated As Integer = CInt(Math.Floor(dipWidth / DashboardGridTokens.CellMinWidthDip))
            If estimated < DashboardGridTokens.MinColumns Then Return DashboardGridTokens.MinColumns
            If estimated > DashboardGridTokens.MaxColumns Then Return DashboardGridTokens.MaxColumns
            Return estimated
        End Function

        Friend Shared Function EnsureVisibleIndex(index As Integer,
                                                  firstIndex As Integer,
                                                  count As Integer,
                                                  visibleCount As Integer) As Integer
            If count <= 0 OrElse visibleCount <= 0 Then Return 0
            Dim normalized As Integer = ClampIndex(index, count)
            Dim first As Integer = Math.Max(0, firstIndex)
            Dim maxFirst As Integer = Math.Max(0, count - visibleCount)
            If normalized < first Then first = normalized
            If normalized >= first + visibleCount Then first = normalized - visibleCount + 1
            If first > maxFirst Then first = maxFirst
            If first < 0 Then first = 0
            Return first
        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, "MASDashboardGridPolicy.ResolveRightToLeft")
                Return False
            End Try
        End Function

        Friend Shared Function BuildSummary(widgetCount As Integer,
                                            selectedIndex As Integer) As String
            If widgetCount <= 0 Then Return "0 widgets"
            Dim selected As String = (Math.Max(0, selectedIndex) + 1).ToString(CultureInfo.CurrentCulture)
            Dim countText As String = widgetCount.ToString(CultureInfo.CurrentCulture)
            Dim noun As String = If(widgetCount = 1, "widget", "widgets")
            Return selected & " / " & countText & " " & noun
        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(DashboardGridTokens.TextAlpha)
            Return Nexamas.UI.Values.Color.Text.Primary.WithAlpha(DashboardGridTokens.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(DashboardGridTokens.MutedTextAlpha)
            Return Nexamas.UI.Values.Color.Text.Secondary.WithAlpha(DashboardGridTokens.MutedTextAlpha)
        End Function

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

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

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

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

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

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

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

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

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

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


        Friend Shared Function HasProviderAdapterPolicyPath() As Boolean
            Dim snapshot As New MASDashboardGridProviderAdapterPolicySnapshot(
                1,
                "dashboardgrid",
                "DashboardGrid.PublicProviderAdapter",
                MASDashboardGridProviderAdapterPolicyMode.InternalProjectionOnly,
                exposesPublicProviderAdapter:=False,
                supportsInternalProviderRefresh:=HasWidgetProviderRefreshContractPath(),
                ownsExternalStorage:=False,
                ownsShellRefreshLoop:=False,
                hasCommandBoundary:=True,
                hasDocumentedPreviewBoundary:=True,
                note:="DashboardGrid provider adapter policy remains internal-only for the promoted visual dashboard boundary.")
            Return snapshot.IsClosedPreviewPolicy
        End Function



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

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

End Namespace
