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 MASChartLegend. It centralizes key/text hygiene,
    ''' item bounds, selection visibility, RTL detection, swatch color fallback,
    ''' theme color resolution, and explicit non-goals. It does not own chart
    ''' rendering, chart data, analytics, queries, providers, storage, or services.
    ''' </summary>
    Friend NotInheritable Class MASChartLegendPolicy
        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 ChartLegendTokens.DefaultTitle
            Return ClampText(text, 64)
        End Function

        Friend Shared Function NormalizeLabel(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return ChartLegendTokens.DefaultItemLabel
            Return ClampText(text, 72)
        End Function

        Friend Shared Function NormalizeValueText(value As String) As String
            Return ClampText(NormalizeText(value), 42)
        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()
            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 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 BuildSummary(itemCount As Integer,
                                            selectedIndex As Integer) As String
            If itemCount <= 0 Then Return "0 items"
            Dim noun As String = If(itemCount = 1, "item", "items")
            Dim countText As String = itemCount.ToString(CultureInfo.CurrentCulture)
            If selectedIndex < 0 Then Return countText & " " & noun
            Return (selectedIndex + 1).ToString(CultureInfo.CurrentCulture) & " / " & countText & " " & noun
        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, "MASChartLegendPolicy.ResolveRightToLeft")
                Return False
            End Try
        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(ChartLegendTokens.TextAlpha)
            Return Nexamas.UI.Values.Color.Text.Primary.WithAlpha(ChartLegendTokens.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(ChartLegendTokens.MutedTextAlpha)
            Return Nexamas.UI.Values.Color.Text.Secondary.WithAlpha(ChartLegendTokens.MutedTextAlpha)
        End Function

        Friend Shared Function ResolveSwatchColor(colorArgb As UInteger,
                                                  index As Integer,
                                                  accent As SKColor) As SKColor
            If colorArgb <> 0UI Then Return New SKColor(colorArgb)
            Select Case Math.Abs(index) Mod 8
                Case 0
                    Return accent
                Case 1
                    Return New SKColor(34, 197, 94)
                Case 2
                    Return New SKColor(245, 158, 11)
                Case 3
                    Return New SKColor(168, 85, 247)
                Case 4
                    Return New SKColor(236, 72, 153)
                Case 5
                    Return New SKColor(14, 165, 233)
                Case 6
                    Return New SKColor(239, 68, 68)
                Case Else
                    Return New SKColor(100, 116, 139)
            End Select
        End Function

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

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

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

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

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

End Namespace
