Option Strict On
Option Explicit On

Imports System.Collections.Generic
Imports System.Globalization
Imports Nexamas.UI.Theming
Imports SkiaSharp

Namespace Nexamas.UI.ThemeStudio

    ''' <summary>
    ''' Deterministic contrast analyzer used by Theme Studio snapshots.
    ''' </summary>
    ''' <remarks>
    ''' The analyzer is classical math only. It has no AI/model dependency, does not mutate
    ''' themes, and does not decide rendering. It emits inspection facts for designers.
    ''' </remarks>
    Friend NotInheritable Class MASThemeStudioContrastAnalyzer
        Private Sub New()
        End Sub

        Friend Shared Function Analyze(theme As IMASAppTheme) As IReadOnlyList(Of MASThemeStudioContrastCheck)
            Dim result As New List(Of MASThemeStudioContrastCheck)()
            If theme Is Nothing Then Return result.AsReadOnly()

            Dim foundation As IMASThemeFoundation = MASAppThemeContracts.Foundation(theme)
            Dim textColors As IMASTextColorTheme = foundation.TextColors
            Dim neutrals As IMASNeutralTheme = foundation.Neutrals
            Dim brand As IMASBrandTheme = foundation.Brand

            If textColors Is Nothing OrElse neutrals Is Nothing OrElse brand Is Nothing Then
                Return result.AsReadOnly()
            End If

            AddCheck(result, theme, "Primary text on Surface0", textColors.PrimaryText, neutrals.Surface0, 4.5R)
            AddCheck(result, theme, "Secondary text on Surface1", textColors.SecondaryText, neutrals.Surface1, 3.0R)
            AddCheck(result, theme, "On-brand text on BrandPrimary", textColors.OnBrandPrimaryText, brand.BrandPrimary, 4.5R)

            Return result.AsReadOnly()
        End Function

        Private Shared Sub AddCheck(result As List(Of MASThemeStudioContrastCheck),
                                    theme As IMASAppTheme,
                                    name As String,
                                    foreground As SKColor,
                                    background As SKColor,
                                    minimumRatio As Double)
            Dim ratio As Double = ContrastRatio(foreground, background)
            result.Add(New MASThemeStudioContrastCheck(
                themeId:=theme.Id,
                name:=name,
                foregroundHex:=ToHex(foreground),
                backgroundHex:=ToHex(background),
                ratio:=ratio,
                minimumRatio:=minimumRatio,
                passes:=ratio >= minimumRatio))
        End Sub

        Private Shared Function ContrastRatio(foreground As SKColor, background As SKColor) As Double
            Dim a As Double = RelativeLuminance(foreground)
            Dim b As Double = RelativeLuminance(background)
            Dim lighter As Double = Math.Max(a, b)
            Dim darker As Double = Math.Min(a, b)
            Return (lighter + 0.05R) / (darker + 0.05R)
        End Function

        Private Shared Function RelativeLuminance(color As SKColor) As Double
            Dim r As Double = Linearized(color.Red / 255.0R)
            Dim g As Double = Linearized(color.Green / 255.0R)
            Dim b As Double = Linearized(color.Blue / 255.0R)
            Return (0.2126R * r) + (0.7152R * g) + (0.0722R * b)
        End Function

        Private Shared Function Linearized(channel As Double) As Double
            If channel <= 0.03928R Then Return channel / 12.92R
            Return Math.Pow((channel + 0.055R) / 1.055R, 2.4R)
        End Function

        Private Shared Function ToHex(color As SKColor) As String
            Return "#" &
                   color.Red.ToString("X2", CultureInfo.InvariantCulture) &
                   color.Green.ToString("X2", CultureInfo.InvariantCulture) &
                   color.Blue.ToString("X2", CultureInfo.InvariantCulture) &
                   color.Alpha.ToString("X2", CultureInfo.InvariantCulture)
        End Function

    End Class

End Namespace
