Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Controls

    ''' <summary>
    ''' Friend-owned presentation policy for MASFormValidationSummary. It centralizes
    ''' text hygiene, count summaries, semantic tone colors, RTL detection, and hard
    ''' ownership boundaries. Validation rule execution, binding, submit orchestration,
    ''' storage, native native validation-host routes, and form engines remain outside.
    ''' </summary>
    Friend NotInheritable Class MASFormValidationSummaryPolicy
        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 FormValidationSummaryTokens.DefaultTitle
            Return ClampText(text, 64)
        End Function

        Friend Shared Function NormalizeFieldLabel(value As String) As String
            Dim text As String = NormalizeText(value)
            If text.Length = 0 Then Return "Field"
            Return ClampText(text, 48)
        End Function

        Friend Shared Function NormalizeMessage(value As String) As String
            Dim text As String = MASValidationMessagePolicy.NormalizeMessageText(value)
            If text.Length = 0 Then Return "Review this field."
            Return ClampText(text.Replace(vbLf, " "), 120)
        End Function

        Friend Shared Function NormalizeState(value As MASTextValidationState) As MASTextValidationState
            Return MASValidationMessagePolicy.NormalizeState(value)
        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 EnsureVisibleIndex(selectedIndex As Integer,
                                                  currentTopIndex As Integer,
                                                  itemCount As Integer,
                                                  visibleCount As Integer) As Integer
            If itemCount <= 0 OrElse visibleCount <= 0 Then Return 0
            Dim maxTop As Integer = Math.Max(0, itemCount - visibleCount)
            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 + visibleCount Then Return Math.Max(0, Math.Min(maxTop, selectedIndex - visibleCount + 1))
            Return top
        End Function

        Friend Shared Function BuildSummary(messageCount As Integer,
                                            errorCount As Integer,
                                            warningCount As Integer) As String
            If messageCount <= 0 Then Return "Ready"
            Dim errorText As String = Math.Max(0, errorCount).ToString(CultureInfo.CurrentCulture) & " errors"
            Dim warningText As String = Math.Max(0, warningCount).ToString(CultureInfo.CurrentCulture) & " warnings"
            Return errorText & " / " & warningText
        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, "MASFormValidationSummaryPolicy.ResolveRightToLeft")
                Return False
            End Try
        End Function

        Friend Shared Function ResolveStateColor(ctx As MASThemeContext,
                                                 state As MASTextValidationState) As SKColor
            Dim color As SKColor = MASValidationMessagePolicy.ResolveStateColor(ctx, state)
            If color.Alpha > 0 Then Return color
            Return ResolveAccentColor(ctx)
        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(FormValidationSummaryTokens.TextAlpha)
            Return Nexamas.UI.Values.Color.Text.Primary.WithAlpha(FormValidationSummaryTokens.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(FormValidationSummaryTokens.MutedTextAlpha)
            Return Nexamas.UI.Values.Color.Text.Secondary.WithAlpha(FormValidationSummaryTokens.MutedTextAlpha)
        End Function

        Friend Shared Function HasOfficialVisualSurface() As Boolean
            Dim type As Type = GetType(MASFormValidationSummary)
            Return type.IsPublic AndAlso
                   type.IsClass AndAlso
                   type.IsSealed AndAlso
                   GetType(MASControlBase).IsAssignableFrom(type) AndAlso
                   GetType(Nexamas.UI.Composition.IMASLayoutParticipant).IsAssignableFrom(type) AndAlso
                   GetType(Nexamas.UI.Layout.IMASIntrinsicSizeContract).IsAssignableFrom(type)
        End Function

        Friend Shared Function HasSemanticToneRoute() As Boolean
            Const flags As BindingFlags = BindingFlags.Static Or BindingFlags.NonPublic
            Return GetType(MASFormValidationSummaryPolicy).GetMethod("ResolveStateColor", flags) IsNot Nothing AndAlso
                   GetType(MASFormValidationSummaryPolicy).GetMethod("ResolveAccentColor", flags) IsNot Nothing
        End Function

        Friend Shared Function HasRtlAwareLayout() As Boolean
            Const flags As BindingFlags = BindingFlags.Static Or BindingFlags.NonPublic
            Return GetType(MASFormValidationSummaryPolicy).GetMethod("ResolveRightToLeft", flags) IsNot Nothing
        End Function

        Friend Shared Function HasNoRuleExecutionPath() As Boolean
            Return Not HasForbiddenMember(GetType(MASFormValidationSummary), "Validate", "Rule", "Predicate")
        End Function

        Friend Shared Function HasNoBindingEnginePath() As Boolean
            Return Not HasForbiddenMember(GetType(MASFormValidationSummary), "Binding", "Binder", "ViewModel")
        End Function

        Friend Shared Function HasNoSubmitOrchestrationPath() As Boolean
            Return Not HasForbiddenMember(GetType(MASFormValidationSummary), "Submit", "CommandRegistry", "CommandAction")
        End Function

        Friend Shared Function HasNoStoragePath() As Boolean
            Return Not HasForbiddenMember(GetType(MASFormValidationSummary), "Storage", "Repository", "File", "Database")
        End Function

        Friend Shared Function HasNoNativeValidationHostPath() As Boolean
            Return Not HasForbiddenMember(GetType(MASFormValidationSummary), "ErrorProvider", "ValidationProvider", "BindingSource")
        End Function

        Friend Shared Function HasMouseFocusRingSuppressed() As Boolean
            Return MASCompositeContentFocusPolicyProbe.PointerFocusDisabled(GetType(MASFormValidationSummary))
        End Function

        Private Shared Function HasForbiddenMember(type As Type,
                                                   ParamArray tokens() As String) As Boolean
            If type Is Nothing OrElse tokens Is Nothing Then Return False
            Const flags As BindingFlags = BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.Public Or BindingFlags.NonPublic
            For Each field As FieldInfo In type.GetFields(flags)
                If ContainsAny(field.Name, tokens) OrElse ContainsAny(field.FieldType.FullName, tokens) Then Return True
            Next
            For Each prop As PropertyInfo In type.GetProperties(flags)
                If ContainsAny(prop.Name, tokens) OrElse ContainsAny(prop.PropertyType.FullName, tokens) Then Return True
            Next
            For Each method As MethodInfo In type.GetMethods(flags)
                If method.IsSpecialName Then Continue For
                If ContainsAny(method.Name, tokens) OrElse ContainsAny(method.ReturnType.FullName, tokens) Then Return True
            Next
            Return False
        End Function

        Private Shared Function ContainsAny(value As String,
                                            tokens As IEnumerable(Of String)) As Boolean
            Dim text As String = If(value, String.Empty)
            For Each token As String In tokens
                If token IsNot Nothing AndAlso token.Length > 0 AndAlso text.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0 Then Return True
            Next
            Return False
        End Function

    Friend NotInheritable Class MASCompositeContentFocusPolicyProbe
        Private Sub New()
        End Sub

        Friend Shared Function PointerFocusDisabled(controlType As Type) As Boolean
            If controlType Is Nothing Then Return False
            Const flags As BindingFlags = BindingFlags.Instance Or BindingFlags.NonPublic
            Dim method As MethodInfo = controlType.GetMethod("WantsPointerFocus", flags)
            If method Is Nothing OrElse method.DeclaringType IsNot controlType Then Return False
            Return method.ReturnType Is GetType(Boolean)
        End Function
    End Class

    End Class

End Namespace
