Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Internal responsive layout facts for MASComboBox field and popup geometry.
    ''' This keeps field chrome, dropdown gap, popup height, and popup row metrics tied
    ''' to the central runtime size profile instead of raw token*dpi sizing.
    ''' </summary>
    Friend NotInheritable Class MASComboBoxLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=260.0F,
            denseWidthDip:=200.0F,
            compactWidthDip:=140.0F,
            minimalWidthDip:=84.0F,
            fullHeightDip:=42.0F,
            denseHeightDip:=34.0F,
            compactHeightDip:=26.0F,
            minimalHeightDip:=18.0F)

        Friend ReadOnly Property ResponsiveProfile As MASResponsiveLayoutProfile
        Friend ReadOnly Property Dpi As Single
        Friend ReadOnly Property MetricScale As Single
        Friend ReadOnly Property MetricDpi As Single
        Friend ReadOnly Property DropGapPx As Single
        Friend ReadOnly Property PopupMaxHeightPx As Single
        Friend ReadOnly Property PopupMinHeightPx As Single
        Friend ReadOnly Property CollapsePopup As Boolean

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        dpi As Single,
                        metricScale As Single,
                        dropGapPx As Single,
                        popupMaxHeightPx As Single,
                        popupMinHeightPx As Single,
                        collapsePopup As Boolean)
            Dim safeDpi As Single = SanitizeScale(dpi, 1.0F)
            Dim safeMetricScale As Single = SanitizeScale(metricScale, 1.0F)

            Me.ResponsiveProfile = profile
            Me.Dpi = safeDpi
            Me.MetricScale = Math.Min(1.22F, Math.Max(0.68F, safeMetricScale))
            Me.MetricDpi = safeDpi * Me.MetricScale
            Me.DropGapPx = Math.Max(0.0F, dropGapPx)
            Me.PopupMaxHeightPx = Math.Max(1.0F, popupMaxHeightPx)
            Me.PopupMinHeightPx = Math.Max(1.0F, Math.Min(popupMinHeightPx, Me.PopupMaxHeightPx))
            Me.CollapsePopup = collapsePopup
        End Sub

        Friend Shared Function Create(ctx As MASThemeContext,
                                      availableBoundsPx As SKRect,
                                      sizeIntent As MASSize) As MASComboBoxLayoutPlan
            Dim profile As MASResponsiveLayoutProfile = MASResponsiveLayoutResolver.FromTheme(ctx, availableBoundsPx, sizeIntent, Thresholds)
            Return Create(profile)
        End Function

        Friend Shared Function Create(profile As MASResponsiveLayoutProfile) As MASComboBoxLayoutPlan
            Dim safeProfile As MASResponsiveLayoutProfile = If(profile, MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, MASSize.Default, Thresholds))
            Dim dpi As Single = safeProfile.DpiScale
            Dim metricScale As Single = ResolveMetricScale(safeProfile)
            Dim maxHeightDip As Single = ResolvePopupMaxHeightDip(safeProfile)
            Dim minHeightDip As Single = ResolvePopupMinHeightDip(safeProfile)

            Return New MASComboBoxLayoutPlan(
                profile:=safeProfile,
                dpi:=dpi,
                metricScale:=metricScale,
                dropGapPx:=safeProfile.GapDipToPx(ComboBoxTokens.DropGapDip),
                popupMaxHeightPx:=safeProfile.ContentDipToPx(maxHeightDip),
                popupMinHeightPx:=safeProfile.ContentDipToPx(minHeightDip),
                collapsePopup:=safeProfile.Mode = MASResponsiveLayoutMode.Collapsed)
        End Function

        Private Shared Function ResolveMetricScale(profile As MASResponsiveLayoutProfile) As Single
            If profile Is Nothing Then Return 1.0F
            Dim scale As Single = Math.Min(profile.ChromeScale, profile.ContentScale)
            If profile.Mode = MASResponsiveLayoutMode.Collapsed Then scale = Math.Min(scale, 0.72F)
            Return Math.Min(1.22F, Math.Max(0.68F, scale))
        End Function

        Private Shared Function ResolvePopupMaxHeightDip(profile As MASResponsiveLayoutProfile) As Single
            If profile Is Nothing Then Return ComboBoxTokens.DropMaxHeightDip

            Select Case profile.Mode
                Case MASResponsiveLayoutMode.Full
                    Return ComboBoxTokens.DropMaxHeightDip
                Case MASResponsiveLayoutMode.Dense
                    Return Math.Min(224.0F, ComboBoxTokens.DropMaxHeightDip)
                Case MASResponsiveLayoutMode.Compact
                    Return Math.Min(176.0F, ComboBoxTokens.DropMaxHeightDip)
                Case MASResponsiveLayoutMode.Minimal
                    Return Math.Min(124.0F, ComboBoxTokens.DropMaxHeightDip)
                Case Else
                    Return Math.Min(76.0F, ComboBoxTokens.DropMaxHeightDip)
            End Select
        End Function

        Private Shared Function ResolvePopupMinHeightDip(profile As MASResponsiveLayoutProfile) As Single
            If profile Is Nothing Then Return ComboBoxTokens.DropMinHeightDip
            If profile.Mode = MASResponsiveLayoutMode.Collapsed Then Return Math.Min(42.0F, ComboBoxTokens.DropMinHeightDip)
            If profile.Mode = MASResponsiveLayoutMode.Minimal Then Return Math.Min(56.0F, ComboBoxTokens.DropMinHeightDip)
            Return ComboBoxTokens.DropMinHeightDip
        End Function

        Private Shared Function SanitizeScale(value As Single,
                                              fallback As Single) As Single
            If Single.IsNaN(value) OrElse Single.IsInfinity(value) OrElse value <= 0.0F Then Return fallback
            Return value
        End Function
    End Class

End Namespace
