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

function New-CIEMConfigPage {
    <#
    .SYNOPSIS
        Creates the CIEM Configuration page.
    .PARAMETER Navigation
        Array of UDListItem components for sidebar navigation.
    #>

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

    $ErrorActionPreference = 'Stop'

    New-UDPage -Name 'Configuration' -Url '/ciem/config' -Content {
        New-UDTypography -Text 'Configuration' -Variant 'h4' -Style @{ marginBottom = '20px'; marginTop = '10px' }
        New-UDTypography -Text 'Configure scheduled discovery and outbound notifications' -Variant 'subtitle1' -Style @{ marginBottom = '30px'; color = '#666' }

        New-UDElement -Tag 'div' -Id 'scheduledDiscoveryWrapper' -Content {
            New-UDCard -Title 'Scheduled Discovery' -Content {
                $scheduleRows = @(Devolutions.CIEM\Get-CIEMAzureDiscoverySchedule)
                $schedule = $scheduleRows | Select-Object -First 1
                $selectedScope = if ($schedule) { [string]$schedule.Scope } else { 'All' }
                $selectedCadence = if (-not $schedule -or $schedule.Cron -eq '0 2 * * *') {
                    'daily'
                }
                elseif ($schedule.Cron -eq '0 2 * * 1') {
                    'weekly'
                }
                else {
                    throw "Unsupported scheduled discovery cron '$($schedule.Cron)'."
                }
                $scheduleEnabled = if ($schedule) { [bool]$schedule.Enabled } else { $false }

                New-UDGrid -Container -Spacing 2 -Content {
                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 4 -Content {
                        New-UDSelect -Id 'azureDiscoveryScheduleCadence' -Label 'Cadence' -DefaultValue $selectedCadence -FullWidth -Option {
                            New-UDSelectOption -Name 'Daily' -Value 'daily'
                            New-UDSelectOption -Name 'Weekly' -Value 'weekly'
                        }
                    }
                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 4 -Content {
                        New-UDSelect -Id 'azureDiscoveryScheduleScope' -Label 'Scope' -DefaultValue $selectedScope -FullWidth -Option {
                            New-UDSelectOption -Name 'All' -Value 'All'
                            New-UDSelectOption -Name 'ARM' -Value 'ARM'
                            New-UDSelectOption -Name 'Entra' -Value 'Entra'
                        }
                    }
                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 2 -Content {
                        New-UDSwitch -Id 'azureDiscoveryScheduleEnabled' -Label 'Enabled' -Checked $scheduleEnabled
                    }
                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 2 -Content {
                        New-UDButton -Id 'saveAzureDiscoveryScheduleBtn' -Text 'Save' -Variant 'contained' -Color 'primary' -ShowLoading -OnClick {
                            try {
                                $cadence = [string](Get-UDElement -Id 'azureDiscoveryScheduleCadence').value
                                $scope = [string](Get-UDElement -Id 'azureDiscoveryScheduleScope').value
                                $enabled = [bool](Get-UDElement -Id 'azureDiscoveryScheduleEnabled').checked

                                $cron = switch ($cadence) {
                                    'daily' { '0 2 * * *' }
                                    'weekly' { '0 2 * * 1' }
                                    default { throw "Unsupported scheduled discovery cadence '$cadence'." }
                                }

                                Devolutions.CIEM\Set-CIEMAzureDiscoverySchedule -Scope $scope -Cron $cron -Enabled $enabled | Out-Null
                                Sync-UDElement -Id 'azureDiscoveryScheduleStatus'
                                Show-UDToast -Message 'Scheduled discovery saved.' -Duration 5000 -BackgroundColor '#4caf50'
                            }
                            catch {
                                Devolutions.CIEM\Write-CIEMLog -Message "Save scheduled discovery failed: $($_.Exception.Message)" -Severity ERROR -Component 'PSU-ConfigPage'
                                Show-UDToast -Message "Scheduled discovery save failed: $($_.Exception.Message)" -Duration 10000 -BackgroundColor '#f44336'
                            }
                        }
                    }
                }

                New-UDDynamic -Id 'azureDiscoveryScheduleStatus' -Content {
                    $currentSchedule = @(Devolutions.CIEM\Get-CIEMAzureDiscoverySchedule) | Select-Object -First 1
                    if ($currentSchedule) {
                        $state = if ($currentSchedule.Enabled) { 'Enabled' } else { 'Disabled' }
                        $lastStatus = if ($currentSchedule.LastStatus) { $currentSchedule.LastStatus } else { 'No scheduled run recorded' }
                        New-UDTypography -Text "$state - $($currentSchedule.Scope) - $($currentSchedule.Cron) - $lastStatus" -Variant 'caption' -Style @{ color = '#666' }
                    }
                    else {
                        New-UDTypography -Text 'Disabled - no schedule configured' -Variant 'caption' -Style @{ color = '#666' }
                    }
                }
            }
        }

        New-UDCard -Title 'Notification Channels' -Content {
            New-UDElement -Tag 'div' -Id 'availableNotificationChannelTypes' -Attributes @{ style = @{ marginBottom = '18px' } } -Content {
                New-UDTypography -Text 'Available Channel Types' -Variant 'subtitle2' -Style @{ marginBottom = '8px'; color = '#555' }
                New-UDStack -Direction 'row' -Spacing 1 -Content {
                    New-UDButton -Id 'addEmailNotificationChannelBtn' -Text 'Add Email Channel' -Variant 'outlined' -Color 'primary' -OnClick {
                        $notificationChannel = @(Devolutions.CIEM\Get-CIEMNotificationChannel -Id 'email-default') | Select-Object -First 1

                        Set-UDElement -Id 'notificationChannelEditorPane' -Content {
                            New-UDElement -Tag 'div' -Attributes @{ style = @{ border = '1px solid #d7dde5'; borderRadius = '6px'; padding = '16px'; marginBottom = '18px'; backgroundColor = '#fafbfc' } } -Content {
                                New-UDTypography -Text 'Email Channel' -Variant 'h6' -Style @{ marginBottom = '12px' }
                                New-UDGrid -Container -Spacing 2 -Content {
                                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 6 -Content {
                                        New-UDTextbox -Id 'notificationFromAddress' -Label 'From Address' -Value $notificationChannel.FromAddress -FullWidth -Placeholder 'ciem@example.com'
                                    }
                                    New-UDGrid -Item -ExtraSmallSize 12 -MediumSize 6 -Content {
                                        New-UDTextbox -Id 'notificationToRecipients' -Label 'To Recipients' -Value (@($notificationChannel.ToRecipients) -join ', ') -FullWidth -Placeholder 'security@example.com, it@example.com'
                                    }
                                }
                                New-UDStack -Direction 'row' -Spacing 2 -Content {
                                    New-UDButton -Id 'saveNotificationsBtn' -Text 'Save' -Variant 'contained' -Color 'primary' -ShowLoading -OnClick {
                                        try {
                                            $parseRecipients = {
                                                param([string]$RecipientText)
                                                if ([string]::IsNullOrWhiteSpace($RecipientText)) { return }
                                                foreach ($recipient in ($RecipientText -split ',')) {
                                                    $trimmedRecipient = $recipient.Trim()
                                                    if (-not [string]::IsNullOrWhiteSpace($trimmedRecipient)) { $trimmedRecipient }
                                                }
                                            }

                                            $toRecipients = [string[]]@(& $parseRecipients ([string](Get-UDElement -Id 'notificationToRecipients').value))

                                            Devolutions.CIEM\Set-CIEMNotificationChannel `
                                                -Enabled $true `
                                                -FromAddress ([string](Get-UDElement -Id 'notificationFromAddress').value) `
                                                -ToRecipients $toRecipients | Out-Null

                                            Set-UDElement -Id 'notificationChannelEditorPane' -Content {}
                                            Sync-UDElement -Id 'notificationChannelsTableRegion'
                                            Show-UDToast -Message 'Notifications saved.' -Duration 5000 -BackgroundColor '#4caf50'
                                        }
                                        catch {
                                            Devolutions.CIEM\Write-CIEMLog -Message "Save notifications failed: $($_.Exception.Message)" -Severity ERROR -Component 'PSU-ConfigPage'
                                            Show-UDToast -Message "Notification save failed: $($_.Exception.Message)" -Duration 10000 -BackgroundColor '#f44336'
                                        }
                                    }
                                    New-UDButton -Id 'cancelNotificationChannelEditBtn' -Text 'Cancel' -Variant 'outlined' -OnClick {
                                        Set-UDElement -Id 'notificationChannelEditorPane' -Content {}
                                    }
                                }
                            }
                        }
                    }
                }
            }

            New-UDElement -Tag 'div' -Id 'notificationChannelEditorPane'

            New-UDDynamic -Id 'notificationChannelsTableRegion' -Content {
                $channels = @(Devolutions.CIEM\Get-CIEMNotificationChannel)
                $channelRows = @(foreach ($channel in $channels) {
                    [PSCustomObject]@{
                        Name          = [string]$channel.Name
                        Type          = [string]$channel.Type
                        Status        = if ($channel.Enabled) { 'Enabled' } else { 'Disabled' }
                        From          = [string]$channel.FromAddress
                        Recipients    = (@($channel.ToRecipients) -join ', ')
                        CcRecipients  = (@($channel.CcRecipients) -join ', ')
                        BccRecipients = (@($channel.BccRecipients) -join ', ')
                        UpdatedAt     = [string]$channel.UpdatedAt
                    }
                })

                New-UDTable -Id 'notificationChannelsTable' -Data $channelRows -Columns @(
                    New-UDTableColumn -Property 'Name' -Title 'Channel'
                    New-UDTableColumn -Property 'Type' -Title 'Type'
                    New-UDTableColumn -Property 'Status' -Title 'Status'
                    New-UDTableColumn -Property 'From' -Title 'From'
                    New-UDTableColumn -Property 'Recipients' -Title 'Recipients'
                ) -Dense -OnRowExpand {
                    New-UDStack -Spacing 1 -Content {
                        New-UDTypography -Text "Status: $($EventData.Status)" -Variant 'caption'
                        New-UDTypography -Text "Cc: $($EventData.CcRecipients)" -Variant 'caption'
                        New-UDTypography -Text "Bcc: $($EventData.BccRecipients)" -Variant 'caption'
                        New-UDTypography -Text "Updated: $($EventData.UpdatedAt)" -Variant 'caption'
                    }
                }
            }
        } -Style @{ marginTop = '24px' }
    } -Navigation $Navigation -NavigationLayout permanent
}