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
    )

    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' }

        # Last Discovery status card
        New-UDDynamic -Content {
            $lastRun = @(Get-CIEMAzureDiscoveryRun -Status 'Completed' -Last 1)
            if ($lastRun.Count -gt 0) {
                $run = $lastRun[0]
                $resourceCount = $run.ArmRowCount + $run.EntraRowCount
                New-UDCard -Title 'Last Discovery' -Style @{ marginBottom = '20px' } -Content {
                    New-UDTypography -Text "Completed: $($run.CompletedAt)" -Variant body2
                    New-UDTypography -Text "Resources: $resourceCount ($($run.ArmRowCount) ARM, $($run.EntraRowCount) Entra)" -Variant body2
                    New-UDTypography -Text "Types: $($run.ArmTypeCount) ARM, $($run.EntraTypeCount) Entra" -Variant body2
                }
            } else {
                New-UDCard -Title 'Discovery' -Style @{ marginBottom = '20px' } -Content {
                    New-UDTypography -Text 'No discovery runs completed yet. Run Start-CIEMAzureDiscovery to populate resource data.' -Variant body2
                }
            }
        }

        # Load available scan runs for the selector (only those with results)
        $scanRuns = @(Get-CIEMScanRun | Where-Object { $_.TotalResults -gt 0 })

        if ($scanRuns -and $scanRuns.Count -gt 0) {
            # Initialize selected scan run to most recent if not already set
            if (-not $Session:SelectedScanRunId) {
                $Session: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 = @(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 $Session:SelectedScanRunId -OnChange {
                            $Session: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 = $Session:SelectedScanRunId
                if (-not $scanRunId) { return }

                $scanRun = 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 { $_.Check.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 = '#9c27b0' }
                                        @{ Name = 'High';     Count = $pHigh;     color = '#f44336' }
                                        @{ Name = 'Medium';   Count = $pMedium;   color = '#ff9800' }
                                        @{ Name = 'Low';      Count = $pLow;      color = '#2196f3' }
                                    ) | Where-Object { $_.Count -gt 0 }
                                    if ($SeverityData.Count -gt 0) {
                                        New-UDChartJS -Type 'doughnut' -Data $SeverityData -DataProperty Count -LabelProperty Name -BackgroundColor @('#9c27b0', '#f44336', '#ff9800', '#2196f3')
                                    } 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 = 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
}