Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Nexamas.UI.Icons
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Controls

    ''' <summary>
    ''' Friend-only presentation policy for MASStatusBanner. It owns product-facing
    ''' text hygiene, tone normalization, semantic icon selection, wrapping/ellipsis,
    ''' RTL text alignment, and theme color resolution. Toast lifetime, notification
    ''' queues, dialogs, validation execution, and command services remain outside it.
    ''' </summary>
    Friend NotInheritable Class MASStatusBannerVisualPolicy

        Friend Const MaxTitleLength As Integer = 120
        Friend Const MaxMessageLength As Integer = 320
        Friend Const MaxMessageLines As Integer = 2

        Private Sub New()
        End Sub

        Friend Shared Function NormalizeText(value As String,
                                             maxLength As Integer) As String
            Dim s As String = If(value, String.Empty)
            s = s.Replace(vbCrLf, vbLf)
            s = s.Replace(vbCr, vbLf)

            Dim rawLines As String() = s.Split(New String() {vbLf}, StringSplitOptions.None)
            Dim result As New StringBuilder(s.Length)

            For Each rawLine As String In rawLines
                Dim line As String = CollapseSpaces(If(rawLine, String.Empty)).Trim()
                If line.Length = 0 Then Continue For
                If result.Length > 0 Then result.Append(vbLf)
                result.Append(line)
            Next

            Dim normalized As String = result.ToString()
            Dim safeMax As Integer = Math.Max(0, maxLength)
            If safeMax > 0 AndAlso normalized.Length > safeMax Then normalized = normalized.Substring(0, safeMax)
            Return normalized
        End Function

        Friend Shared Function NormalizeTitle(value As String) As String
            Return NormalizeText(value, MaxTitleLength)
        End Function

        Friend Shared Function NormalizeMessage(value As String) As String
            Return NormalizeText(value, MaxMessageLength)
        End Function

        Friend Shared Function NormalizeTone(value As MASToastTone) As MASToastTone
            Select Case value
                Case MASToastTone.Neutral, MASToastTone.Success, MASToastTone.Info, MASToastTone.Warning, MASToastTone.Danger
                    Return value
                Case Else
                    Return MASToastTone.Info
            End Select
        End Function

        Friend Shared Function ResolveTitleText(title As String,
                                                tone As MASToastTone) As String
            Dim normalized As String = NormalizeTitle(title)
            If normalized.Length > 0 Then Return normalized
            Return ResolveDefaultTitle(tone)
        End Function

        Friend Shared Function ResolveMessageText(message As String) As String
            Dim normalized As String = NormalizeMessage(message)
            If normalized.Length > 0 Then Return normalized
            Return "Status information"
        End Function

        Friend Shared Function ResolveIconKind(tone As MASToastTone) As MASIconKind
            Select Case NormalizeTone(tone)
                Case MASToastTone.Success
                    Return MASIconKind.Success
                Case MASToastTone.Warning
                    Return MASIconKind.Warning
                Case MASToastTone.Danger
                    Return MASIconKind.Failure
                Case Else
                    Return MASIconKind.Info
            End Select
        End Function


        Friend Shared Function ResolveAccentSegmentWidth(showIcon As Boolean) As Single
            If showIcon Then Return StatusBannerTokens.AccentSegmentWithIconWidthDip
            Return StatusBannerTokens.AccentSegmentWithoutIconWidthDip
        End Function

        Friend Shared Function ResolveToneColor(ctx As MASThemeContext,
                                                tone As MASToastTone) As SKColor
            If ctx IsNot Nothing AndAlso ctx.SemanticTheme IsNot Nothing Then
                Select Case NormalizeTone(tone)
                    Case MASToastTone.Success
                        Return ctx.SemanticTheme.Success
                    Case MASToastTone.Warning
                        Return ctx.SemanticTheme.Warning
                    Case MASToastTone.Danger
                        Return ctx.SemanticTheme.Danger
                    Case MASToastTone.Info
                        Return ctx.SemanticTheme.Info
                End Select
            End If

            If NormalizeTone(tone) = MASToastTone.Neutral AndAlso ctx IsNot Nothing AndAlso ctx.BrandTheme IsNot Nothing Then
                Return ctx.BrandTheme.BrandPrimary
            End If

            If ctx IsNot Nothing AndAlso ctx.SemanticTheme IsNot Nothing Then Return ctx.SemanticTheme.Info
            Return SKColors.Gray
        End Function

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

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

        Friend Shared Function BuildWrappedLines(text As String,
                                                 paint As SKPaint,
                                                 maxWidthPx As Single,
                                                 maxLines As Integer) As List(Of String)
            Dim result As New List(Of String)()
            Dim s As String = NormalizeText(text, If(maxLines <= 1, MaxTitleLength, MaxMessageLength))
            If s.Length = 0 OrElse paint Is Nothing Then Return result

            Dim safeWidth As Single = Math.Max(12.0F, maxWidthPx)
            Dim safeMaxLines As Integer = Math.Max(1, maxLines)
            Dim explicitLines As String() = s.Split(New String() {vbLf}, StringSplitOptions.None)

            For Each explicitLine As String In explicitLines
                AddWrappedLine(result, explicitLine, paint, safeWidth, safeMaxLines)
                If result.Count >= safeMaxLines Then Exit For
            Next

            If result.Count > safeMaxLines Then result.RemoveRange(safeMaxLines, result.Count - safeMaxLines)
            If result.Count = safeMaxLines AndAlso result.Count > 0 Then
                result(result.Count - 1) = FitLastLine(result(result.Count - 1), paint, safeWidth)
            End If

            Return result
        End Function

        Friend Shared Function ResolveTextIsRtl(title As String,
                                                message As String) As Boolean
            Dim probe As String = (If(title, String.Empty) & " " & If(message, String.Empty)).Trim()
            If probe.Length = 0 Then Return Nexamas.UI.Localization.MASLocalization.IsCurrentRightToLeft()
            Try
                Return MASShapedText.IsRtl(probe)
            Catch masCaughtException1 As Exception
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowTextShapingFallback(masCaughtException1)
                Return Nexamas.UI.Localization.MASLocalization.IsCurrentRightToLeft()
            End Try
        End Function

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

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

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

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

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

        Private Shared Function ResolveDefaultTitle(tone As MASToastTone) As String
            Select Case NormalizeTone(tone)
                Case MASToastTone.Success
                    Return "Success"
                Case MASToastTone.Warning
                    Return "Warning"
                Case MASToastTone.Danger
                    Return "Error"
                Case MASToastTone.Neutral
                    Return "Status"
                Case Else
                    Return "Information"
            End Select
        End Function

        Private Shared Sub AddWrappedLine(result As List(Of String),
                                          line As String,
                                          paint As SKPaint,
                                          maxWidthPx As Single,
                                          maxLines As Integer)
            If result Is Nothing OrElse paint Is Nothing Then Return
            If result.Count >= maxLines Then Return

            Dim cleanLine As String = CollapseSpaces(If(line, String.Empty)).Trim()
            If cleanLine.Length = 0 Then Return

            Dim words As String() = cleanLine.Split(New Char() {" "c}, StringSplitOptions.RemoveEmptyEntries)
            Dim current As String = String.Empty

            For Each word As String In words
                Dim candidate As String = If(current.Length = 0, word, current & " " & word)
                If MASShapedText.MeasureWidth(candidate, paint) <= maxWidthPx OrElse current.Length = 0 Then
                    current = candidate
                Else
                    result.Add(current)
                    If result.Count >= maxLines Then Return
                    current = word
                End If
            Next

            If current.Length > 0 AndAlso result.Count < maxLines Then result.Add(current)
        End Sub

        Private Shared Function FitLastLine(value As String,
                                            paint As SKPaint,
                                            maxWidthPx As Single) As String
            Dim s As String = If(value, String.Empty)
            If s.Length = 0 OrElse paint Is Nothing Then Return s
            If MASShapedText.MeasureWidth(s, paint) <= maxWidthPx Then Return s
            Return Nexamas.UI.MASTextCore.FitEllipsis(s, maxWidthPx, paint)
        End Function

        Private Shared Function CollapseSpaces(value As String) As String
            If String.IsNullOrEmpty(value) Then Return String.Empty

            Dim result As New StringBuilder(value.Length)
            Dim previousWasSpace As Boolean
            For Each ch As Char In value
                If ch = ControlChars.Lf Then
                    result.Append(ch)
                    previousWasSpace = False
                    Continue For
                End If

                Dim isSpace As Boolean = Char.IsWhiteSpace(ch)
                If isSpace Then
                    If Not previousWasSpace Then result.Append(" "c)
                    previousWasSpace = True
                Else
                    result.Append(ch)
                    previousWasSpace = False
                End If
            Next

            Return result.ToString()
        End Function

    End Class

End Namespace
