modules/Devolutions.CIEM.PSU/Pages/New-CIEMDashboardPage.ps1

function New-CIEMDashboardPage {
    <#
    .SYNOPSIS
        Creates the Dashboard page showing scan results overview and severity charts.
    .PARAMETER Navigation
        Array of UDListItem components for sidebar navigation.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [object[]]$Navigation
    )

    $ErrorActionPreference = 'Stop'

    New-UDPage -Name 'Dashboard' -Url '/ciem' -Content {
        New-UDTypography -Text 'Devolutions CIEM Dashboard' -Variant 'h4' -Style @{ marginBottom = '10px'; marginTop = '10px' }
        New-UDTypography -Text 'Cloud Infrastructure Entitlement Management - Scan Results Overview' -Variant 'subtitle1' -Style @{ marginBottom = '20px'; color = '#666' }

        $scanRuns = @(Devolutions.CIEM\Get-CIEMScanRun | Where-Object { $_.TotalResults -gt 0 })
        $needsAttentionItems = @(Devolutions.CIEM\Get-CIEMDashboardNeedsAttention -Limit 3)
        $pamProgress = Devolutions.CIEM\Get-CIEMPAMProgressSummary -Limit 5
        $scanEfficiency = Devolutions.CIEM\Get-CIEMScanEfficiencySummary -Last 5
        $graphCountRows = @(Devolutions.CIEM\Invoke-CIEMQuery -Query 'SELECT COUNT(*) AS c FROM graph_nodes')
        if ($graphCountRows.Count -ne 1) {
            throw "Expected one graph node count row, got $($graphCountRows.Count)."
        }
        $hasDiscoveryGraphData = [int]$graphCountRows[0].c -gt 0

        $latestScanState = if ($scanRuns.Count -gt 0) { [string]$scanRuns[0].Status } else { 'No scan data' }
        $identityDataState = if ($hasDiscoveryGraphData) { 'Present' } else { 'None' }
        $pamReadiness = "$($pamProgress.ReadinessPercent)%"
        New-UDElement -Tag 'section' -Id 'dashboardOverviewSection' -Attributes @{
            style = @{
                display = 'grid'
                gap = '12px'
                marginBottom = '16px'
            }
        } -Content {
            New-UDElement -Id 'dashboardPrimaryStateGrid' -Tag 'div' -Attributes @{
                style = @{
                    display = 'grid'
                    gridTemplateColumns = 'repeat(4, minmax(0, 1fr))'
                    gap = '10px'
                }
            } -Content {
                foreach ($metric in @(
                    @{ Label = 'Needs Attention'; Value = [string]$needsAttentionItems.Count; Detail = 'Priority risk items' },
                    @{ Label = 'Identity Data'; Value = $identityDataState; Detail = 'Discovery graph state' },
                    @{ Label = 'Latest Scan'; Value = $latestScanState; Detail = 'Checks and scan state' },
                    @{ Label = 'PAM Readiness'; Value = $pamReadiness; Detail = 'Implementation progress' }
                )) {
                    New-UDElement -Tag 'div' -Attributes @{
                        'data-ciem-dashboard-status-metric' = 'true'
                        style = @{
                            display = 'grid'
                            gap = '3px'
                            minHeight = '82px'
                            padding = '12px'
                            border = '1px solid #d0d7de'
                            borderRadius = '6px'
                            backgroundColor = '#ffffff'
                        }
                    } -Content {
                        New-UDTypography -Text $metric.Label -Variant 'caption' -Style @{ color = '#57606a'; fontWeight = '600' }
                        New-UDTypography -Text $metric.Value -Variant 'h5' -Style @{ color = '#24292f'; fontWeight = '700'; lineHeight = '1.1' }
                        New-UDTypography -Text $metric.Detail -Variant 'caption' -Style @{ color = '#57606a' }
                    }
                }
            }
        }

        New-UDElement -Tag 'section' -Id 'dashboardPriorityWorkSection' -Attributes @{
            style = @{
                display = 'grid'
                gap = '14px'
                alignItems = 'start'
                marginBottom = '18px'
            }
        } -Content {

        New-UDElement -Tag 'section' -Id 'dashboardNeedsAttentionSection' -Attributes @{
            style = @{
                marginBottom = '22px'
            }
        } -Content {
            New-UDTypography -Text 'Needs Attention' -Variant 'h5' -Style @{ marginBottom = '6px' }
            New-UDTypography -Text 'Highest-priority identity and attack path risks from the current discovery graph.' -Variant 'body2' -Style @{ marginBottom = '12px'; color = '#666' }

            if ($needsAttentionItems.Count -eq 0) {
                $emptyText = if ($hasDiscoveryGraphData) {
                    'No current identity or attack path risks need attention.'
                } else {
                    'No discovered identity or attack path data yet. Run discovery to build the risk queue.'
                }
                New-UDElement -Tag 'div' -Attributes @{
                    'data-ciem-needs-attention-empty' = 'true'
                    style = @{
                        padding = '14px'
                        border = '1px solid #d0d7de'
                        borderRadius = '6px'
                        backgroundColor = '#ffffff'
                    }
                } -Content {
                    New-UDTypography -Text $emptyText -Variant 'body2' -Style @{ color = '#666' }
                }
            } else {
                New-UDElement -Tag 'div' -Attributes @{ style = @{ display = 'grid'; gap = '10px' } } -Content {
                    foreach ($item in $needsAttentionItems) {
                        $severityColor = Devolutions.CIEM\Get-SeverityColor -Severity $item.Severity
                        New-UDElement -Tag 'div' -Attributes @{
                            'data-ciem-needs-attention-item' = 'true'
                            style = @{
                                display = 'grid'
                                gap = '8px'
                                padding = '12px'
                                border = '1px solid #d0d7de'
                                borderRadius = '6px'
                                backgroundColor = '#ffffff'
                            }
                        } -Content {
                            New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                                New-UDChip -Label $item.Severity -Size 'small' -Style @{ backgroundColor = $severityColor; color = 'white' }
                                New-UDChip -Label $item.SourceType -Size 'small' -Variant 'outlined'
                                New-UDTypography -Text $item.Title -Variant 'subtitle1' -Style @{ fontWeight = '600' }
                            }
                            New-UDTypography -Text "Identity: $($item.Identity)" -Variant 'body2' -Style @{ color = '#555' }
                            New-UDTypography -Text "Target: $($item.Target)" -Variant 'body2' -Style @{ color = '#555'; overflowWrap = 'anywhere' }
                            New-UDTypography -Text $item.Reason -Variant 'body2'
                            New-UDTypography -Text $item.Evidence -Variant 'caption' -Style @{ color = '#666'; overflowWrap = 'anywhere' }
                            if ($item.SourceType -eq 'Identity') {
                                New-UDElement -Tag 'div' -Attributes @{ 'data-ciem-inspect-identity' = 'true' } -Content {
                                    New-UDButton -Text 'Inspect Identity' -Variant 'outlined' -Size 'small' -OnClick {
                                        Invoke-UDRedirect '/ciem/identities'
                                    }
                                }
                            } elseif ($item.SourceType -eq 'AttackPath') {
                                New-UDElement -Tag 'div' -Attributes @{ 'data-ciem-inspect-attack-path' = 'true' } -Content {
                                    $drillInUrl = [string]$item.DrillInUrl
                                    if ([string]::IsNullOrWhiteSpace($drillInUrl)) {
                                        throw "Expected dashboard Needs Attention attack path '$($item.Id)' to include DrillInUrl."
                                    }
                                    New-UDButton -Text 'Inspect Attack Path' -Variant 'outlined' -Size 'small' -OnClick {
                                        Invoke-UDRedirect $drillInUrl
                                    }
                                }
                            } else {
                                throw "Unsupported dashboard Needs Attention item source type '$($item.SourceType)'."
                            }
                        }
                    }
                }
            }
        }

            if ($scanRuns.Count -eq 0) {
                New-UDElement -Tag 'div' -Id 'dashboardNoScanDataState' -Attributes @{
                    style = @{
                        marginTop = '4px'
                        textAlign = 'center'
                        padding = '28px'
                        border = '1px solid #d0d7de'
                        borderRadius = '6px'
                        backgroundColor = '#ffffff'
                    }
                } -Content {
                    New-UDStack -Direction 'column' -AlignItems 'center' -Spacing 2 -Content {
                        New-UDIcon -Icon 'Search' -Size '3x' -Style @{ color = '#1976d2'; marginBottom = '8px' }
                        New-UDTypography -Text 'No Scan Data Available' -Variant 'h5' -Style @{ marginBottom = '4px' }
                        New-UDTypography -Text 'Run a security scan to populate the dashboard.' -Variant 'body1' -Style @{ color = '#666'; marginBottom = '12px' }
                        New-UDButton -Text 'Run Your First Scan' -Variant 'contained' -Color 'primary' -Size 'medium' -OnClick {
                            Invoke-UDRedirect '/ciem/scan'
                        }
                    }
                }
            }
        }

        New-UDElement -Tag 'section' -Id 'dashboardSupportingEvidenceSection' -Attributes @{
            style = @{
                display = 'grid'
                gap = '18px'
            }
        } -Content {
            New-UDExpansionPanelGroup -Id 'dashboardSupportingEvidencePanelGroup' -Type 'Accordion' -Children {
                New-UDExpansionPanel -Id 'dashboardIdentityAndPAMPanel' -Title 'Identity & PAM' -Children {
                    New-UDElement -Tag 'section' -Id 'dashboardIdentitySection' -Attributes @{ style = @{ marginBottom = '20px' } } -Content {
                        New-UDTypography -Text 'Identity Stats' -Variant 'h5' -Style @{ marginBottom = '6px' }
                        New-UDTypography -Text 'Identity inventory and effective entitlement coverage.' -Variant 'body2' -Style @{ marginBottom = '16px'; color = '#666' }

                        $identityStatsRows = @(Devolutions.CIEM\Invoke-CIEMQuery -Query @"
SELECT
    (SELECT COUNT(*) FROM graph_nodes WHERE kind IN ('EntraUser', 'EntraServicePrincipal', 'EntraGroup')) AS identity_count,
    (SELECT COUNT(*) FROM azure_effective_role_assignments) AS entitlement_count
"@
)
                        if ($identityStatsRows.Count -ne 1) {
                            throw "Expected one dashboard identity stats row, got $($identityStatsRows.Count)."
                        }

                        $identityStats = $identityStatsRows[0]
                        $identityCount = [int]$identityStats.identity_count
                        $entitlementCount = [int]$identityStats.entitlement_count

                        New-UDGrid -Container -Content {
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Identities' -Content {
                                    New-UDTypography -Text $identityCount -Variant 'h3' -Style @{ color = '#1976d2'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Entitlements' -Content {
                                    New-UDTypography -Text $entitlementCount -Variant 'h3' -Style @{ color = '#7b1fa2'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                        }
                    }

        New-UDElement -Tag 'section' -Id 'dashboardPAMProgressSection' -Attributes @{
            style = @{
                marginBottom = '22px'
            }
        } -Content {
            New-UDTypography -Text 'PAM Implementation Progress' -Variant 'h5' -Style @{ marginBottom = '6px' }
            New-UDTypography -Text 'Read-only CIEM progress toward PAM adoption: readiness, candidate mapping, and scoped handoff status.' -Variant 'body2' -Style @{ marginBottom = '12px'; color = '#666' }
            $riskBurndownMetric = if ($null -eq $pamProgress.RiskBurndownPercent) { 'No baseline' } else { "$($pamProgress.RiskBurndownPercent)%" }

            New-UDElement -Tag 'div' -Attributes @{
                style = @{
                    display = 'grid'
                    gridTemplateColumns = 'repeat(auto-fit, minmax(160px, 1fr))'
                    gap = '10px'
                    marginBottom = '12px'
                }
            } -Content {
                foreach ($metric in @(
                    @{ Label = 'Readiness'; Value = "$($pamProgress.ReadinessPercent)%" },
                    @{ Label = 'PAM Candidates'; Value = [string]$pamProgress.PAMCandidateCount },
                    @{ Label = 'Risk Burndown'; Value = $riskBurndownMetric }
                )) {
                    New-UDElement -Tag 'div' -Attributes @{
                        'data-ciem-pam-progress-metric' = 'true'
                        style = @{
                            padding = '12px'
                            border = '1px solid #d0d7de'
                            borderRadius = '6px'
                            backgroundColor = '#ffffff'
                        }
                    } -Content {
                        New-UDTypography -Text $metric.Label -Variant 'caption' -Style @{ color = '#666' }
                        New-UDTypography -Text $metric.Value -Variant 'h6' -Style @{ marginTop = '4px' }
                    }
                }
            }

            New-UDElement -Tag 'div' -Attributes @{ style = @{ display = 'grid'; gap = '8px'; marginBottom = '12px' } } -Content {
                foreach ($stage in @($pamProgress.Stages)) {
                    $stageColor = switch ([string]$stage.Status) {
                        'Complete' { '#2e7d32' }
                        'Pending' { '#ed6c02' }
                        'NotScoped' { '#5f6368' }
                        default { throw "Unsupported PAM progress stage status '$($stage.Status)'." }
                    }
                    New-UDElement -Tag 'div' -Attributes @{
                        'data-ciem-pam-progress-stage' = 'true'
                        style = @{
                            display = 'grid'
                            gap = '6px'
                            padding = '10px 12px'
                            border = '1px solid #d0d7de'
                            borderRadius = '6px'
                            backgroundColor = '#ffffff'
                        }
                    } -Content {
                        New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                            New-UDChip -Label $stage.Status -Size 'small' -Style @{ backgroundColor = $stageColor; color = 'white' }
                            New-UDTypography -Text $stage.Name -Variant 'subtitle2' -Style @{ fontWeight = '600' }
                        }
                        New-UDTypography -Text $stage.Evidence -Variant 'caption' -Style @{ color = '#666'; overflowWrap = 'anywhere' }
                    }
                }
            }

            if ($pamProgress.Candidates.Count -eq 0) {
                New-UDElement -Tag 'div' -Attributes @{
                    'data-ciem-pam-progress-empty' = 'true'
                    style = @{
                        padding = '14px'
                        border = '1px solid #d0d7de'
                        borderRadius = '6px'
                        backgroundColor = '#ffffff'
                    }
                } -Content {
                    New-UDTypography -Text 'No PAM candidates are mapped yet.' -Variant 'body2' -Style @{ color = '#666' }
                }
            }
            else {
                New-UDElement -Tag 'div' -Attributes @{ style = @{ display = 'grid'; gap = '10px' } } -Content {
                    foreach ($candidate in @($pamProgress.Candidates)) {
                        $severityColor = Devolutions.CIEM\Get-SeverityColor -Severity $candidate.Severity
                        New-UDElement -Tag 'div' -Attributes @{
                            'data-ciem-pam-progress-candidate' = 'true'
                            style = @{
                                display = 'grid'
                                gap = '7px'
                                padding = '12px'
                                border = '1px solid #d0d7de'
                                borderRadius = '6px'
                                backgroundColor = '#ffffff'
                            }
                        } -Content {
                            New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                                New-UDChip -Label $candidate.Severity -Size 'small' -Style @{ backgroundColor = $severityColor; color = 'white' }
                                New-UDChip -Label $candidate.SourceType -Size 'small' -Variant 'outlined'
                                New-UDTypography -Text $candidate.Title -Variant 'subtitle1' -Style @{ fontWeight = '600' }
                            }
                            New-UDTypography -Text $candidate.PAMCapability -Variant 'body2' -Style @{ color = '#555' }
                            New-UDTypography -Text $candidate.RecommendedNextStep -Variant 'caption' -Style @{ color = '#666'; overflowWrap = 'anywhere' }
                        }
                    }
                }
            }
        }

                }

                New-UDExpansionPanel -Id 'dashboardChecksAndScansPanel' -Title 'Checks & Scans' -Children {
        New-UDElement -Tag 'section' -Id 'dashboardScanEfficiencySection' -Attributes @{
            style = @{
                marginBottom = '22px'
            }
        } -Content {
            New-UDTypography -Text 'Scan Efficiency' -Variant 'h5' -Style @{ marginBottom = '6px' }
            New-UDTypography -Text 'Duration and throughput from persisted scan runs and discovery phase timing.' -Variant 'body2' -Style @{ marginBottom = '12px'; color = '#666' }

            if ($scanEfficiency.Status -eq 'NoScanData') {
                New-UDElement -Tag 'div' -Attributes @{
                    'data-ciem-scan-efficiency-empty' = 'true'
                    style = @{
                        padding = '14px'
                        border = '1px solid #d0d7de'
                        borderRadius = '6px'
                        backgroundColor = '#ffffff'
                    }
                } -Content {
                    New-UDTypography -Text 'No timed scan runs are available yet.' -Variant 'body2' -Style @{ color = '#666' }
                }
            }
            elseif ($scanEfficiency.Status -eq 'Tracked') {
                $latestDurationText = "$($scanEfficiency.LatestDurationSeconds)s"
                $averageDurationText = "$($scanEfficiency.AverageDurationSeconds)s"
                $latestThroughputText = if ($null -eq $scanEfficiency.LatestResultsPerSecond) { 'No throughput' } else { "$($scanEfficiency.LatestResultsPerSecond) results/s" }
                $averageThroughputText = if ($null -eq $scanEfficiency.AverageResultsPerSecond) { 'No throughput' } else { "$($scanEfficiency.AverageResultsPerSecond) results/s" }

                New-UDElement -Tag 'div' -Attributes @{
                    style = @{
                        display = 'grid'
                        gridTemplateColumns = 'repeat(auto-fit, minmax(160px, 1fr))'
                        gap = '10px'
                        marginBottom = '12px'
                    }
                } -Content {
                    foreach ($metric in @(
                        @{ Label = 'Latest Duration'; Value = $latestDurationText },
                        @{ Label = 'Average Duration'; Value = $averageDurationText },
                        @{ Label = 'Latest Throughput'; Value = $latestThroughputText },
                        @{ Label = 'Average Throughput'; Value = $averageThroughputText }
                    )) {
                        New-UDElement -Tag 'div' -Attributes @{
                            'data-ciem-scan-efficiency-metric' = 'true'
                            style = @{
                                padding = '12px'
                                border = '1px solid #d0d7de'
                                borderRadius = '6px'
                                backgroundColor = '#ffffff'
                            }
                        } -Content {
                            New-UDTypography -Text $metric.Label -Variant 'caption' -Style @{ color = '#666' }
                            New-UDTypography -Text $metric.Value -Variant 'h6' -Style @{ marginTop = '4px' }
                        }
                    }
                }

                New-UDElement -Tag 'div' -Attributes @{ style = @{ display = 'grid'; gap = '8px' } } -Content {
                    foreach ($run in @($scanEfficiency.Runs)) {
                        New-UDElement -Tag 'div' -Attributes @{
                            'data-ciem-scan-efficiency-run' = 'true'
                            style = @{
                                display = 'grid'
                                gap = '6px'
                                padding = '10px 12px'
                                border = '1px solid #d0d7de'
                                borderRadius = '6px'
                                backgroundColor = '#ffffff'
                            }
                        } -Content {
                            New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                                New-UDChip -Label $run.Status -Size 'small' -Variant 'outlined'
                                New-UDTypography -Text $run.Id -Variant 'subtitle2' -Style @{ fontWeight = '600'; overflowWrap = 'anywhere' }
                            }
                            New-UDTypography -Text "Duration: $($run.DurationSeconds)s; Results: $($run.TotalResults); Failed: $($run.FailedResults); Throughput: $($run.ResultsPerSecond) results/s" -Variant 'caption' -Style @{ color = '#666'; overflowWrap = 'anywhere' }
                        }
                    }
                }
            }
            else {
                throw "Unsupported scan efficiency status '$($scanEfficiency.Status)'."
            }

            $discoveryPhaseMetrics = @($scanEfficiency.LatestDiscoveryPhaseMetrics)
            if ($discoveryPhaseMetrics.Count -gt 0) {
                $discoveryDurationText = "$($scanEfficiency.LatestDiscoveryDurationSeconds)s"
                New-UDElement -Tag 'div' -Id 'dashboardDiscoveryPhaseTiming' -Attributes @{
                    style = @{
                        display = 'grid'
                        gap = '8px'
                        marginTop = '12px'
                    }
                } -Content {
                    New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                        New-UDTypography -Text 'Discovery Phase Timing' -Variant 'subtitle1' -Style @{ fontWeight = '600' }
                        New-UDChip -Label "Run #$($scanEfficiency.LatestDiscoveryRunId)" -Size 'small' -Variant 'outlined'
                        New-UDChip -Label "Total Discovery Duration: $discoveryDurationText" -Size 'small' -Variant 'outlined'
                    }
                    foreach ($phase in $discoveryPhaseMetrics) {
                        $phaseStatusLabel = if ($phase.Succeeded) { 'Succeeded' } else { 'Failed' }
                        $phaseStatusColor = if ($phase.Succeeded) { '#2e7d32' } else { '#d32f2f' }
                        New-UDElement -Tag 'div' -Attributes @{
                            'data-ciem-discovery-phase-metric' = 'true'
                            style = @{
                                display = 'grid'
                                gap = '6px'
                                padding = '10px 12px'
                                border = '1px solid #d0d7de'
                                borderRadius = '6px'
                                backgroundColor = '#ffffff'
                            }
                        } -Content {
                            New-UDStack -Direction 'row' -Spacing 1 -AlignItems 'center' -Content {
                                New-UDChip -Label $phaseStatusLabel -Size 'small' -Style @{ backgroundColor = $phaseStatusColor; color = 'white' }
                                New-UDTypography -Text $phase.PhaseName -Variant 'subtitle2' -Style @{ fontWeight = '600'; overflowWrap = 'anywhere' }
                            }
                            New-UDTypography -Text "Duration: $($phase.ElapsedSeconds)s; Evidence: $($phase.Evidence)" -Variant 'caption' -Style @{ color = '#666'; overflowWrap = 'anywhere' }
                        }
                    }
                }
            }
        }

        New-UDElement -Tag 'section' -Id 'dashboardScanSection' -Attributes @{ style = @{ marginBottom = '28px' } } -Content {
            New-UDTypography -Text 'Checks & Scans' -Variant 'h5' -Style @{ marginBottom = '6px' }
            New-UDTypography -Text 'Cloud checks, scan results, and finding evidence.' -Variant 'body2' -Style @{ marginBottom = '16px'; color = '#666' }

            if ($scanRuns -and $scanRuns.Count -gt 0) {
                # Initialize selected scan run to most recent if not already set
                if (-not $Page:SelectedScanRunId) {
                    $Page:SelectedScanRunId = $scanRuns[0].Id
                }

                # Scan Run Selector + Run New Scan button
                New-UDElement -Tag 'div' -Attributes @{ style = @{ marginBottom = '20px' } } -Content {
                    New-UDStack -Direction 'row' -Spacing 2 -AlignItems 'center' -Content {
                        New-UDElement -Tag 'div' -Attributes @{ style = @{ minWidth = '400px' } } -Content {
                            New-UDSelect -Id 'scanRunSelector' -Label 'Select Scan Run' -Option {
                                $runs = @(Devolutions.CIEM\Get-CIEMScanRun | Where-Object { $_.TotalResults -gt 0 })
                                foreach ($run in $runs) {
                                    $statusIcon = switch ([string]$run.Status) { 'Completed' { '✓' } 'Failed' { '✗' } default { '…' } }
                                    $label = "$statusIcon $(([datetime]$run.StartTime).ToString('yyyy-MM-dd HH:mm')) - $($run.Providers -join ', ') ($($run.TotalResults) results, $($run.FailedResults) failed)"
                                    New-UDSelectOption -Name $label -Value $run.Id
                                }
                            } -DefaultValue $Page:SelectedScanRunId -OnChange {
                                $Page:SelectedScanRunId = $EventData
                                Sync-UDElement -Id 'dashboardContent'
                            } -FullWidth
                        }
                        New-UDButton -Text 'Run New Scan' -Variant 'outlined' -Size 'small' -OnClick {
                            Invoke-UDRedirect '/ciem/scan'
                        }
                    }
                }

                # Dynamic dashboard content that refreshes when scan run selection changes
                New-UDDynamic -Id 'dashboardContent' -Content {
                    $scanRunId = $Page:SelectedScanRunId
                    if (-not $scanRunId) { return }

                    $scanRun = Devolutions.CIEM\Get-CIEMScanRun -Id $scanRunId -IncludeResults
                    if (-not $scanRun) {
                        New-UDTypography -Text 'Scan run not found.' -Style @{ color = '#666'; padding = '20px' }
                        return
                    }

                    $rawResults = $scanRun.ScanResults
                    $scanTimestamp = $scanRun.EndTime

                    if ($rawResults -and @($rawResults).Count -gt 0) {
                        $ScanResults = $rawResults | ForEach-Object {
                            [PSCustomObject]@{
                                Id = $_.Check.Id
                                CheckId = $_.Check.Id
                                Title = $_.Check.Title
                                Severity = ([string]$_.Check.Severity -replace '^(.)', { $_.Groups[1].Value.ToUpper() })
                                Status = $_.Status
                                Provider = if ($_.Check.Provider) { [string]$_.Check.Provider } else { 'Azure' }
                                Service = [string]$_.Check.Service
                                ResourceName = $_.ResourceName
                            }
                        }

                        $FailedResults = @($ScanResults | Where-Object { $_.Status -eq 'FAIL' })
                        $PassedResults = @($ScanResults | Where-Object { $_.Status -eq 'PASS' })
                        $CriticalCount = @($FailedResults | Where-Object { $_.Severity.ToUpper() -eq 'CRITICAL' }).Count
                        $HighCount = @($FailedResults | Where-Object { $_.Severity.ToUpper() -eq 'HIGH' }).Count
                        $MediumCount = @($FailedResults | Where-Object { $_.Severity.ToUpper() -eq 'MEDIUM' }).Count
                        $LowCount = @($FailedResults | Where-Object { $_.Severity.ToUpper() -eq 'LOW' }).Count

                        New-UDGrid -Container -Content {
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Total Results' -Content {
                                    New-UDTypography -Text @($ScanResults).Count -Variant 'h3' -Style @{ color = '#1976d2'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Failed Checks' -Content {
                                    New-UDTypography -Text $FailedResults.Count -Variant 'h3' -Style @{ color = '#f44336'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Passed Checks' -Content {
                                    New-UDTypography -Text $PassedResults.Count -Variant 'h3' -Style @{ color = '#4caf50'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                            New-UDGrid -Item -ExtraSmallSize 12 -SmallSize 6 -MediumSize 3 -Content {
                                New-UDCard -Title 'Critical Issues' -Content {
                                    New-UDTypography -Text $CriticalCount -Variant 'h3' -Style @{ color = '#9c27b0'; textAlign = 'center' }
                                } -Style @{ textAlign = 'center' }
                            }
                        }

                        # Chart panels: one pair per provider when multi-provider, single pair otherwise
                        $chartProviders = @($scanRun.Providers | Where-Object { $_ })
                        if (-not $chartProviders -or $chartProviders.Count -eq 0) { $chartProviders = @('Azure') }

                        foreach ($chartProvider in $chartProviders) {
                            $providerResults  = @($ScanResults | Where-Object { $_.Provider -eq $chartProvider })
                            $providerFailed   = @($providerResults | Where-Object { $_.Status -eq 'FAIL' })
                            $pCritical = @($providerFailed | Where-Object { $_.Severity.ToUpper() -eq 'CRITICAL' }).Count
                            $pHigh     = @($providerFailed | Where-Object { $_.Severity.ToUpper() -eq 'HIGH' }).Count
                            $pMedium   = @($providerFailed | Where-Object { $_.Severity.ToUpper() -eq 'MEDIUM' }).Count
                            $pLow      = @($providerFailed | Where-Object { $_.Severity.ToUpper() -eq 'LOW' }).Count

                            if ($chartProviders.Count -gt 1) {
                                New-UDTypography -Text $chartProvider -Variant 'h6' -Style @{ marginTop = '16px'; marginBottom = '4px'; color = '#555' }
                            }

                            New-UDGrid -Container -Content {
                                New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 6 -Content {
                                    New-UDCard -Title "Results by Severity$(if ($chartProviders.Count -gt 1) { " - $chartProvider" })" -Content {
                                        $SeverityData = @(
                                            @{ Name = 'Critical'; Count = $pCritical; color = (Devolutions.CIEM\Get-SeverityColor -Severity 'critical') }
                                            @{ Name = 'High';     Count = $pHigh;     color = (Devolutions.CIEM\Get-SeverityColor -Severity 'high') }
                                            @{ Name = 'Medium';   Count = $pMedium;   color = (Devolutions.CIEM\Get-SeverityColor -Severity 'medium') }
                                            @{ Name = 'Low';      Count = $pLow;      color = (Devolutions.CIEM\Get-SeverityColor -Severity 'low') }
                                        ) | Where-Object { $_.Count -gt 0 }
                                        if ($SeverityData.Count -gt 0) {
                                            New-UDChartJS -Type 'doughnut' -Data $SeverityData -DataProperty Count -LabelProperty Name -BackgroundColor @($SeverityData.ForEach({ $_.color }))
                                        } else {
                                            New-UDTypography -Text 'No failed results' -Style @{ textAlign = 'center'; padding = '40px' }
                                        }
                                    }
                                }
                                New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 6 -Content {
                                    New-UDCard -Title "Results by Service$(if ($chartProviders.Count -gt 1) { " - $chartProvider" })" -Content {
                                        $ServiceData = $providerFailed | Group-Object -Property Service | ForEach-Object { @{ Name = $_.Name; Count = $_.Count } }
                                        if ($ServiceData.Count -gt 0) {
                                            New-UDChartJS -Type 'bar' -Data $ServiceData -DataProperty Count -LabelProperty Name -BackgroundColor '#1976d2'
                                        } else {
                                            New-UDTypography -Text 'No failed results' -Style @{ textAlign = 'center'; padding = '40px' }
                                        }
                                    }
                                }
                            }
                        }

                        New-UDCard -Title 'Critical & High Results' -Style @{ marginTop = '20px' } -Content {
                            $CriticalHighResults = $FailedResults | Where-Object { $_.Severity.ToUpper() -in @('CRITICAL', 'HIGH') } | Select-Object -First 5
                            if (@($CriticalHighResults).Count -gt 0) {
                                New-UDTable -Data $CriticalHighResults -Columns @(
                                    New-UDTableColumn -Property 'CheckId' -Title 'Check ID'
                                    New-UDTableColumn -Property 'Title' -Title 'Result'
                                    New-UDTableColumn -Property 'Severity' -Title 'Severity' -Render {
                                        $sev = $EventData.Severity.ToUpper()
                                        $color = Devolutions.CIEM\Get-SeverityColor -Severity $sev
                                        New-UDChip -Label $sev -Style @{ backgroundColor = $color; color = 'white' }
                                    }
                                    New-UDTableColumn -Property 'Service' -Title 'Service'
                                    New-UDTableColumn -Property 'ResourceName' -Title 'Resource'
                                )
                                New-UDButton -Text 'View All Results' -Variant 'outlined' -OnClick {
                                    Invoke-UDRedirect '/ciem/history'
                                } -Style @{ marginTop = '12px' }
                            } else {
                                New-UDStack -Direction 'column' -AlignItems 'center' -Content {
                                    New-UDIcon -Icon 'CheckCircle' -Size '3x' -Style @{ color = '#4caf50'; marginBottom = '12px' }
                                    New-UDTypography -Text 'No critical or high severity results!' -Style @{ color = '#4caf50' }
                                }
                            }
                        }
                    }
                    else {
                        New-UDTypography -Text 'No results for this scan run.' -Style @{ color = '#666'; padding = '20px' }
                    }
                } -LoadingComponent {
                    New-UDProgress -Circular
                }
            }
            else {
                # No scan data - show empty state with call to action
                New-UDCard -Style @{ marginTop = '20px'; textAlign = 'center'; padding = '40px' } -Content {
                    New-UDStack -Direction 'column' -AlignItems 'center' -Spacing 3 -Content {
                        New-UDIcon -Icon 'Search' -Size '4x' -Style @{ color = '#1976d2'; marginBottom = '16px' }
                        New-UDTypography -Text 'No Scan Data Available' -Variant 'h5' -Style @{ marginBottom = '8px' }
                        New-UDTypography -Text 'Run a security scan to see results and insights about your cloud environment.' -Variant 'body1' -Style @{ color = '#666'; marginBottom = '24px' }
                        New-UDButton -Text 'Run Your First Scan' -Variant 'contained' -Color 'primary' -Size 'large' -OnClick {
                            Invoke-UDRedirect '/ciem/scan'
                        }
                    }
                }
            }
        }

                }
            }
        }
    } -Navigation $Navigation -NavigationLayout permanent
}