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 MASCalendarView. It centralizes date normalization,
    ''' culture-aware month/week labels, range clamping, RTL detection, theme color
    ''' resolution, and explicit non-goals for agenda/scheduler ownership.
    ''' </summary>
    Friend NotInheritable Class MASCalendarViewPolicy
        Private Sub New()
        End Sub

        Friend Shared Function NormalizeTitle(value As String) As String
            Dim text As String = If(value, String.Empty).Trim()
            If text.Length = 0 Then text = CalendarViewTokens.DefaultTitle
            If text.Length > 80 Then text = text.Substring(0, 80).TrimEnd() & "…"
            Return text
        End Function

        Friend Shared Function NormalizeDate(value As Date) As Date
            Return value.Date
        End Function

        Friend Shared Function FirstOfMonth(value As Date) As Date
            Dim safe As Date = NormalizeDate(value)
            Return New Date(safe.Year, safe.Month, 1)
        End Function

        Friend Shared Function NormalizeNullableDate(value As Nullable(Of Date)) As Nullable(Of Date)
            If Not value.HasValue Then Return Nothing
            Return NormalizeDate(value.Value)
        End Function

        Friend Shared Function NormalizeDisplayMonth(value As Date) As Date
            Return FirstOfMonth(value)
        End Function

        Friend Shared Function AddMonthsSafe(value As Date,
                                             delta As Integer) As Date
            Try
                Return FirstOfMonth(value).AddMonths(delta)
            Catch ex As ArgumentOutOfRangeException
                Nexamas.UI.Diagnostics.MASExceptionSilencer.SwallowRecoverable(ex, "MASCalendarViewPolicy.AddMonthsSafe")
                If delta < 0 Then Return New Date(1, 1, 1)
                Return New Date(9999, 12, 1)
            End Try
        End Function

        Friend Shared Function ClampToRange(value As Date,
                                            minimumDate As Nullable(Of Date),
                                            maximumDate As Nullable(Of Date)) As Date
            Dim normalized As Date = NormalizeDate(value)
            If minimumDate.HasValue AndAlso normalized < minimumDate.Value Then Return minimumDate.Value
            If maximumDate.HasValue AndAlso normalized > maximumDate.Value Then Return maximumDate.Value
            Return normalized
        End Function

        Friend Shared Function IsDateEnabled(value As Date,
                                             minimumDate As Nullable(Of Date),
                                             maximumDate As Nullable(Of Date)) As Boolean
            Dim normalized As Date = NormalizeDate(value)
            If minimumDate.HasValue AndAlso normalized < minimumDate.Value Then Return False
            If maximumDate.HasValue AndAlso normalized > maximumDate.Value Then Return False
            Return True
        End Function

        Friend Shared Function ResolveFirstDayOfWeek() As DayOfWeek
            Dim culture As CultureInfo = CultureInfo.CurrentCulture
            If culture IsNot Nothing AndAlso culture.DateTimeFormat IsNot Nothing Then
                Return culture.DateTimeFormat.FirstDayOfWeek
            End If
            Return DayOfWeek.Monday
        End Function

        Friend Shared Function ResolveRightToLeft() As Boolean
            Return Nexamas.UI.Localization.MASLocalization.IsCurrentRightToLeft()
        End Function

        Friend Shared Function BuildVisibleDates(displayMonth As Date,
                                                 firstDayOfWeek As DayOfWeek) As Date()
            Dim first As Date = FirstOfMonth(displayMonth)
            Dim offset As Integer = (CInt(first.DayOfWeek) - CInt(firstDayOfWeek) + 7) Mod 7
            Dim startDate As Date = first.AddDays(-offset)
            Dim values(41) As Date
            For i As Integer = 0 To values.Length - 1
                values(i) = startDate.AddDays(i)
            Next
            Return values
        End Function

        Friend Shared Function BuildWeekdayLabels(firstDayOfWeek As DayOfWeek) As String()
            Dim result(6) As String
            Dim formatInfo As DateTimeFormatInfo = CultureInfo.CurrentCulture.DateTimeFormat
            Dim labels As String() = If(formatInfo IsNot Nothing, formatInfo.AbbreviatedDayNames, DateTimeFormatInfo.InvariantInfo.AbbreviatedDayNames)
            For i As Integer = 0 To result.Length - 1
                Dim dayIndex As Integer = (CInt(firstDayOfWeek) + i) Mod 7
                Dim label As String = labels(dayIndex)
                If String.IsNullOrWhiteSpace(label) Then label = CType(dayIndex, DayOfWeek).ToString().Substring(0, 2)
                result(i) = label
            Next
            Return result
        End Function

        Friend Shared Function BuildMonthTitle(displayMonth As Date) As String
            Return FirstOfMonth(displayMonth).ToString("MMMM yyyy", CultureInfo.CurrentCulture)
        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(CalendarViewTokens.PrimaryTextAlpha)
            Return Nexamas.UI.Values.Color.Text.Primary.WithAlpha(CalendarViewTokens.PrimaryTextAlpha)
        End Function

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

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

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

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

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

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

End Namespace
