Option Strict On
Option Explicit On

Namespace Nexamas.UI.Rendering

    Friend NotInheritable Class MASSurfaceMaterialSlotRoutingAudit

        Private Sub New()
        End Sub

        Friend Shared Function Build() As MASSurfaceMaterialSlotRoutingReport
            Dim profiles As MASSurfaceMaterialSlotProfile() = MASSurfaceMaterialSlotProfileRegistry.RegisteredProfiles()
            Dim profileCount As Integer = If(profiles Is Nothing, 0, profiles.Length)
            Dim assignmentCount As Integer = 0
            Dim canonicalAssignmentCount As Integer = 0
            Dim nativeProfileCount As Integer = 0
            Dim keepsElementAgnostic As Boolean = True

            If profiles IsNot Nothing Then
                For Each profile As MASSurfaceMaterialSlotProfile In profiles
                    If profile Is Nothing Then
                        keepsElementAgnostic = False
                        Continue For
                    End If

                    If Not IsCanonicalProfileId(profile.Id) OrElse ContainsElementSpecificTerm(profile.Id) Then keepsElementAgnostic = False

                    Dim hasNativeAssignment As Boolean = False
                    For Each assignment As MASSurfaceMaterialSlotAssignment In profile.Assignments()
                        If assignment Is Nothing Then
                            keepsElementAgnostic = False
                            Continue For
                        End If

                        assignmentCount += 1
                        If assignment.Slot = MASSurfaceSlot.Unknown OrElse Not MASSurfaceSlotCatalog.IsGenericSlotName(assignment.Slot) Then keepsElementAgnostic = False
                        If ContainsElementSpecificTerm(assignment.MaterialKey) Then keepsElementAgnostic = False

                        Dim canonicalKey As String = MASSurfaceMaterialRegistry.Canonicalize(assignment.MaterialKey)
                        Dim definition As MASSurfaceMaterialDefinition = MASSurfaceMaterialRegistry.ResolveDefinition(canonicalKey)
                        If definition IsNot Nothing AndAlso
                           String.Equals(definition.Id, canonicalKey, System.StringComparison.OrdinalIgnoreCase) AndAlso
                           definition.Id.StartsWith("surface.material.", System.StringComparison.OrdinalIgnoreCase) Then
                            canonicalAssignmentCount += 1
                            If definition.PreservesMaterialIdentity Then hasNativeAssignment = True
                        End If
                    Next

                    If hasNativeAssignment Then nativeProfileCount += 1
                Next
            End If

            Dim materialKeyRoute As MASSurfaceMaterialSlotRoute = MASSurfaceMaterialSlotResolver.ResolveMaterialKey(
                consumerKind:=MASSurfaceTreatmentConsumerKind.CardSurface,
                materialKey:="crystal ice native",
                slot:=MASSurfaceSlot.Header,
                fallbackRole:=MASSurfaceRole.Card)
            Dim hasMaterialKeyRoute As Boolean = materialKeyRoute IsNot Nothing AndAlso
                                             String.Equals(materialKeyRoute.MaterialKey, MASSurfaceMaterialIds.CrystalIceNative, System.StringComparison.OrdinalIgnoreCase)

            Dim profileRoute As MASSurfaceMaterialSlotRoute = MASSurfaceMaterialSlotResolver.ResolveProfileSlot(
                consumerKind:=MASSurfaceTreatmentConsumerKind.CardSurface,
                profileId:=MASSurfaceMaterialProfileIds.PremiumGlass,
                slot:=MASSurfaceSlot.Header,
                fallbackRole:=MASSurfaceRole.Card)
            Dim hasProfileSlotRoute As Boolean = profileRoute IsNot Nothing AndAlso
                                                 String.Equals(profileRoute.MaterialKey, MASSurfaceMaterialIds.FrostedGlass, System.StringComparison.OrdinalIgnoreCase)

            Dim hasDesignerProfileProjection As Boolean = profileCount >= 5

            Dim status As MASSurfaceMaterialSlotRoutingStatus = MASSurfaceMaterialSlotRoutingStatus.SlotRoutingReady
            If profileCount < 5 OrElse assignmentCount = 0 Then status = MASSurfaceMaterialSlotRoutingStatus.MissingProfiles
            If assignmentCount <> canonicalAssignmentCount Then status = MASSurfaceMaterialSlotRoutingStatus.BlockedByNonCanonicalMaterial
            If Not keepsElementAgnostic Then status = MASSurfaceMaterialSlotRoutingStatus.BlockedByElementSpecificProfileName
            If Not hasMaterialKeyRoute OrElse Not hasProfileSlotRoute OrElse Not hasDesignerProfileProjection Then status = MASSurfaceMaterialSlotRoutingStatus.BlockedByResolverFailure

            Return New MASSurfaceMaterialSlotRoutingReport(
                name:="Surface Material Slot Routing",
                status:=status,
                profileCount:=profileCount,
                assignmentCount:=assignmentCount,
                canonicalAssignmentCount:=canonicalAssignmentCount,
                nativeProfileCount:=nativeProfileCount,
                hasMaterialKeyRoute:=hasMaterialKeyRoute,
                hasProfileSlotRoute:=hasProfileSlotRoute,
                hasDesignerProfileProjection:=hasDesignerProfileProjection,
                keepsProfilesElementAgnostic:=keepsElementAgnostic)
        End Function

        Private Shared Function IsCanonicalProfileId(profileId As String) As Boolean
            Dim safeId As String = If(profileId, String.Empty).Trim()
            Return safeId.StartsWith("surface.material-profile.", System.StringComparison.OrdinalIgnoreCase)
        End Function

        Private Shared Function ContainsElementSpecificTerm(value As String) As Boolean
            Dim key As String = If(value, String.Empty).Trim().ToLowerInvariant()
            If key.Length = 0 Then Return True

            Dim blockedTerms As String() = New String() {"button", "grid", "avatar", "preview", "date", "time", "menu", "toast", "tooltip", "progressbar", "imageviewer"}
            For Each term As String In blockedTerms
                If key.IndexOf(term, System.StringComparison.Ordinal) >= 0 Then Return True
            Next

            Return False
        End Function

    End Class

End Namespace
