<#
.SYNOPSIS
    Modernizes existing AnywhereNow/Anywhere365 UCC sites for MC1117115 compliance.
.DESCRIPTION
    This script performs IN-PLACE modernization of existing UCC sites by:
    - Adding the UCC Dashboard web part to a modern Home.aspx page
    - Setting the modern page as the homepage
    Works for both site collections AND subsites. No data migration required.
    IMPORTANT: The ucc-dashboard-spfx.sppkg must be deployed tenant-wide BEFORE running this script.
    Run Deploy-UccDashboard.ps1 on each customer tenant first.
.PARAMETER SiteUrl
    The URL of the UCC site to modernize (can be a site collection or subsite)
.PARAMETER Mode
    - Analyze: Only analyze the site, report what needs modernization (default)
    - Modernize: Perform in-place modernization
.PARAMETER Interactive
    Use interactive browser-based authentication
.PARAMETER ClientId
    Azure AD App Client ID for authentication
.PARAMETER CertificatePath
    Path to certificate for app-only authentication
.PARAMETER CertificatePassword
    Password for the certificate (SecureString)
.PARAMETER Tenant
    Tenant name for app-only authentication (e.g., "contoso.onmicrosoft.com")
.PARAMETER Force
    Skip confirmation prompts and re-run modernization even if site appears already modernized
.PARAMETER PreserveLegacyScripts
    Preserve legacy ScriptLink custom actions during modernization. Use this when testing 
    modernization on a few subsites while other subsites still run on v8.3.0.1 or earlier.
    The legacy scripts are needed for older UCC dashboards to function properly.
    Once all sites are modernized, re-run without this parameter to complete the cleanup.
.EXAMPLE
    # Analyze a site (safe - no changes made)
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode Analyze -Interactive -ClientId "your-client-id"
.EXAMPLE
    # Modernize a site collection
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode Modernize -Interactive -ClientId "your-client-id"
.EXAMPLE
    # Modernize a subsite
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc/subsite1" -Mode Modernize -Interactive -ClientId "your-client-id"
.EXAMPLE
    # Modernize a nested subsite (sub-subsite) under a regional grouping
    # Works at any depth - the script connects directly to the specified URL
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc/france/paris-ucc" -Mode Modernize -Interactive -ClientId "your-client-id"
.EXAMPLE
    # Re-modernize an already modernized site (force refresh)
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode Modernize -Interactive -ClientId "your-client-id" -Force
.EXAMPLE
    # App-only authentication for automation (certificate password will be prompted)
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode Modernize -ClientId "app-id" -CertificatePath ".\cert.pfx" -Tenant "contoso.onmicrosoft.com" -Force
.EXAMPLE
    # Test modernization on one subsite while keeping other v8.3.0.1 sites functional
    .\Modernize-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc/test-site" -Mode Modernize -Interactive -ClientId "your-client-id" -PreserveLegacyScripts
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory=$true)]
    [string]$SiteUrl,
    [Parameter(Mandatory=$false)]
    [ValidateSet("Analyze", "Modernize")]
    [string]$Mode = "Analyze",
    [switch]$Interactive,
    [string]$ClientId,
    [string]$CertificatePath,
    [SecureString]$CertificatePassword,
    [string]$Tenant,
    [switch]$Force,
    [switch]$PreserveLegacyScripts,
    [string]$SiteCollectionAppCatalogUrl,
    [switch]$UseSiteCollectionAppCatalog
)
# Check PowerShell version - PnP.PowerShell 3.x requires PowerShell 7.4.6+
if ($PSVersionTable.PSVersion.Major -lt 7 -or 
    ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 4)) {
    Write-Host ""
    Write-Host "ERROR: This script requires PowerShell 7.4.6 or higher." -ForegroundColor Red
    Write-Host "You are running: PowerShell $($PSVersionTable.PSVersion)" -ForegroundColor Red
    Write-Host ""
    Write-Host "Windows PowerShell 5.1 is not supported by PnP.PowerShell 3.x" -ForegroundColor Yellow
    Write-Host ""
    Write-Host "Please install PowerShell 7:" -ForegroundColor Cyan
    Write-Host "  https://aka.ms/PSWindows" -ForegroundColor White
    Write-Host ""
    Write-Host "Or run: winget install Microsoft.PowerShell" -ForegroundColor White
    Write-Host ""
    exit 1
}

$ErrorActionPreference = "Stop"
# Script info
$ScriptVersion = "8.4.1.8"
$ScriptDir = $PSScriptRoot
if ([string]::IsNullOrEmpty($ScriptDir)) {
    $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
}

# UCC Dashboard Web Part Component ID (from manifest)
$uccDashboardComponentId = "12345678-1234-1234-1234-123456789abc"

# Output helpers
function Write-Info($msg) { Write-Host "Info : $msg" -ForegroundColor Cyan }
function Write-Success($msg) { Write-Host "Success : $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host "Warning : $msg" -ForegroundColor Yellow }
function Write-Err($msg) { Write-Host "Error : $msg" -ForegroundColor Red }

function Invoke-HideLeftNavigation {
    <#
    .SYNOPSIS
        Hides the left navigation (Quick Launch) on the current connected site.
    .DESCRIPTION
        Applies multiple methods to suppress the left navigation panel, including
        CSOM, REST, ChromeOptions, and navigation inheritance breaking. This is
        called for all sites in the hierarchy - including intermediate grouping
        subsites that are otherwise skipped - so that deeply nested UCC subsites
        do not inherit a visible left nav from their parent.
    #>
    # Hide left navigation (Quick Launch) for cleaner full-width experience
    try {
        Write-Info "Hiding left navigation for full-width layout..."
    
        # Check if this is a classic site (BLANKINTERNET#0 or similar publishing template)
        $webTemplate = (Get-PnPWeb -Includes WebTemplate, Configuration).WebTemplate
        $isClassicSite = $webTemplate -in @("BLANKINTERNET", "CMSPUBLISHING", "PUBLISHING", "STS")
    
        if ($isClassicSite) {
            Write-Info "Classic site detected ($webTemplate) - applying navigation settings..."
        
            # For classic sites rendered in modern UI: The left nav is controlled by
            # the modern shell, not classic navigation settings
        
            # Try classic property bag approach first
            try {
                Set-PnPPropertyBagValue -Key "__NavigationShowSiblings" -Value "false" -Confirm:$false -ErrorAction SilentlyContinue
                Set-PnPPropertyBagValue -Key "__CurrentNavigationIncludeTypes" -Value "0" -Confirm:$false -ErrorAction SilentlyContinue
                Set-PnPPropertyBagValue -Key "vti_quicklaunchlinksvisible" -Value "false" -Confirm:$false -ErrorAction SilentlyContinue
            }
            catch { }
        
            # For classic sites with modern UI rendering, we still need the modern approaches
            # The QuickLaunchEnabled property should work even on classic templates
            try {
                $ctx = Get-PnPContext
                $web = $ctx.Web
                $ctx.Load($web)
                $ctx.ExecuteQuery()
            
                $web.QuickLaunchEnabled = $false
                $web.Update()
                $ctx.ExecuteQuery()
                Write-Info "QuickLaunchEnabled set to false"
            }
            catch { }
        }
    
        # First: Break navigation inheritance for subsites (critical for nested subsites)
        # Subsites often inherit navigation from parent, which overrides our QuickLaunch settings
        try {
            $ctx = Get-PnPContext
            $web = $ctx.Web
            $nav = $web.Navigation
            $ctx.Load($nav)
            $ctx.ExecuteQuery()
        
            # Set CurrentNavigation to not inherit from parent
            # UseShared = false means "don't inherit from parent"
            $nav.UseShared = $false
            $ctx.ExecuteQuery()
            Write-Info "Navigation inheritance disabled"
        }
        catch {
            # May fail on root sites or if already not inheriting - that's OK
        }
    
        # Method 1: Set QuickLaunchEnabled via CSOM (works for classic sites)
        $web = Get-PnPWeb -ErrorAction Stop
        $web.QuickLaunchEnabled = $false
        $web.Update()
        Invoke-PnPQuery -ErrorAction SilentlyContinue
    
        # Method 2: For modern sites, set the horizontal navigation and hide vertical nav
        # This uses the REST API to set navigation style
        try {
            $ctx = Get-PnPContext
            # Set navigation settings - hiding the left nav
            # NavigationStyle: 0 = Cascading, 1 = Megamenu, 2 = None/Horizontal only
            $web.LoadNavigationElements = $false
            $ctx.Load($web.Navigation)
            $ctx.ExecuteQuery()
        }
        catch { }
    
        # Method 3: Remove all quick launch navigation nodes (clears the menu items)
        try {
            $navNodes = Get-PnPNavigationNode -Location QuickLaunch -ErrorAction SilentlyContinue
            foreach ($node in $navNodes) {
                Remove-PnPNavigationNode -Identity $node.Id -Force -ErrorAction SilentlyContinue
            }
            Write-Info "Removed quick launch navigation nodes"
        }
        catch { }
    
        # Method 4: Set header layout to minimal and menu visibility via REST
        try {
            $web = Get-PnPWeb -ErrorAction SilentlyContinue
            # HeaderLayout: 1 = Standard, 2 = Compact, 3 = Minimal, 4 = Extended
            $web.HeaderLayout = 3  # Minimal - this often hides the left nav too
            $web.Update()
            Invoke-PnPQuery -ErrorAction SilentlyContinue
            Write-Info "Set header layout to minimal"
        }
        catch { }
    
        # Method 5: For modern Communication Sites (and subsites), use REST API to hide vertical nav
        try {
            # Get site URL for REST calls
            $siteUrl = (Get-PnPWeb).Url
        
            # Try setting the navigation visibility via REST
            $body = @{
                menuState = @{
                    quickLaunchEnabled = $false
                }
            } | ConvertTo-Json -Depth 10
        
            Invoke-PnPSPRestMethod -Method Post -Url "$siteUrl/_api/web/Navigation" -Content $body -ContentType "application/json" -ErrorAction SilentlyContinue
        }
        catch { }
    
        # Method 6: Try Set-PnPWeb if available (newer PnP versions)
        try {
            Set-PnPWeb -QuickLaunchEnabled:$false -ErrorAction SilentlyContinue
        }
        catch { }
    
        # Method 7: For modern sites, use CSOM to set MenuState (most reliable for Communication Sites)
        try {
            $ctx = Get-PnPContext
            $web = $ctx.Web
            $ctx.Load($web)
            $ctx.ExecuteQuery()
        
            # Set the vertical navigation to not show (this is what controls the left panel)
            # MegaMenuEnabled = false, QuickLaunchEnabled = false
            $web.MegaMenuEnabled = $false
            $web.QuickLaunchEnabled = $false
            $web.Update()
            $ctx.ExecuteQuery()
            Write-Info "Set MegaMenu and QuickLaunch to disabled via CSOM"
        }
        catch { }
    
        # Method 8: Try REST API to set navigation visibility (modern sites)
        try {
            $webUrl = (Get-PnPWeb).ServerRelativeUrl
        
            # Set the QuickLaunchEnabled property via REST
            $restUrl = "/_api/web"
            $body = '{"__metadata":{"type":"SP.Web"},"QuickLaunchEnabled":false}'
        
            Invoke-PnPSPRestMethod -Method Merge -Url $restUrl -Content $body -ContentType "application/json;odata=verbose" -ErrorAction SilentlyContinue
            Write-Info "Set QuickLaunchEnabled via REST API"
        }
        catch { }
    
        # Method 9: Set HorizontalQuickLaunch to true (hides vertical nav on modern sites)
        try {
            $ctx = Get-PnPContext
            $web = $ctx.Web
            $ctx.Load($web)
            $ctx.ExecuteQuery()
        
            # HorizontalQuickLaunch = true means "use horizontal navigation only" (hides left panel)
            $web.HorizontalQuickLaunch = $true
            $web.Update()
            $ctx.ExecuteQuery()
            Write-Info "Set HorizontalQuickLaunch to true (hiding vertical navigation)"
        }
        catch {
            # Property might not exist on older SharePoint versions
        }
    
        # Method 10: Try setting navigation visibility via modern site chrome REST endpoint
        try {
            # This uses the modern site chrome API
            $body = @{
                "isVerticalNavEnabled" = $false
            } | ConvertTo-Json
        
            Invoke-PnPSPRestMethod -Method Post -Url "/_api/web/SetChromeOptions" -Content $body -ContentType "application/json" -ErrorAction SilentlyContinue
            Write-Info "Disabled vertical navigation via ChromeOptions"
        }
        catch { }
    
        # Set AnywhereNow site logo (replacing any legacy branding)
        try {
            Write-Info "Setting AnywhereNow site logo..."
            $logoLocalPath = Join-Path $ScriptDir "AnywhereNow\Assets\AWN-Master-logo-Full-Colour-RGB.png"
            if (Test-Path $logoLocalPath) {
                $logoSet = $false
                # Method 1: Set-PnPSite -LogoFilePath (Communication Sites without Group)
                try {
                    Set-PnPSite -LogoFilePath $logoLocalPath -ErrorAction Stop
                    Write-Success "Site logo set (AnywhereNow)"
                    $logoSet = $true
                }
                catch {
                    Write-Info "Set-PnPSite failed, trying fallback methods..."
                }
                # Method 2: Upload to SiteAssets and use Set-PnPWebHeader (Group-connected sites)
                if (-not $logoSet) {
                    try {
                        $uploadedFile = Add-PnPFile -Path $logoLocalPath -Folder "SiteAssets" -ErrorAction Stop
                        $serverRelativeUrl = $uploadedFile.ServerRelativeUrl
                        Set-PnPWebHeader -SiteLogoUrl $serverRelativeUrl -ErrorAction Stop
                        Write-Success "Site logo set via WebHeader (AnywhereNow)"
                        $logoSet = $true
                    }
                    catch {
                        Write-Info "Set-PnPWebHeader failed, trying Set-PnPWeb..."
                    }
                }
                # Method 3: Set-PnPWeb -SiteLogoUrl (classic fallback)
                if (-not $logoSet) {
                    try {
                        if (-not $serverRelativeUrl) {
                            $uploadedFile = Add-PnPFile -Path $logoLocalPath -Folder "SiteAssets" -ErrorAction SilentlyContinue
                            $serverRelativeUrl = $uploadedFile.ServerRelativeUrl
                        }
                        Set-PnPWeb -SiteLogoUrl $serverRelativeUrl -ErrorAction Stop
                        Write-Success "Site logo set via Web (AnywhereNow)"
                        $logoSet = $true
                    }
                    catch {
                        Write-Warn "Could not set site logo: $($_.Exception.Message)"
                    }
                }
            }
            else {
                Write-Warn "Logo file not found at: $logoLocalPath"
            }
        }
        catch {
            Write-Warn "Logo setting failed: $($_.Exception.Message)"
        }
    
    
        Write-Success "Navigation settings applied"
    }
    catch {
        Write-Warn "Could not hide left navigation: $($_.Exception.Message)"
    }
}

# ============================================================================
# Load configuration.xml fallback for missing parameters
# ============================================================================
# If authentication parameters are not provided on the command line, try to read them
# from configuration.xml (same pattern as UCC.Site.Creator.ps1 and Shared.ps1)
if (-not $Interactive) {
    $configPath = Join-Path $ScriptDir "configuration.xml"
    if (Test-Path $configPath) {
        Write-Info "Reading fallback parameters from configuration.xml"
        try {
            $configXml = [xml](Get-Content -Path $configPath -Raw -Encoding UTF8)
            if ($configXml.Configuration) {
                # ClientId fallback from CertificateAppId
                if ([string]::IsNullOrEmpty($ClientId) -and -not [string]::IsNullOrEmpty($configXml.Configuration.CertificateAppId)) {
                    $ClientId = $configXml.Configuration.CertificateAppId.Trim()
                    Write-Info "Using ClientId from configuration.xml"
                }
                # Tenant fallback from CertificateTenantId
                if ([string]::IsNullOrEmpty($Tenant) -and -not [string]::IsNullOrEmpty($configXml.Configuration.CertificateTenantId)) {
                    $Tenant = $configXml.Configuration.CertificateTenantId.Trim()
                    Write-Info "Using Tenant from configuration.xml"
                }
                # CertificatePath fallback
                if ([string]::IsNullOrEmpty($CertificatePath) -and -not [string]::IsNullOrEmpty($configXml.Configuration.CertificatePath)) {
                    $CertificatePath = $configXml.Configuration.CertificatePath.Trim()
                    Write-Info "Using CertificatePath from configuration.xml"
                }
                # CertificatePassword fallback (handles encrypted attribute)
                if ($null -eq $CertificatePassword) {
                    $certPwd = $null
                    $encrypted = $configXml.Configuration.CertificatePassword.encrypted
                    if ($null -ne $encrypted) {
                        $certPwd = $configXml.Configuration.CertificatePassword.InnerText
                    }
                    else {
                        $certPwd = $configXml.Configuration.CertificatePassword
                    }
                    if (-not [string]::IsNullOrEmpty($certPwd)) {
                        $certPwd = $certPwd.Trim()
                        if ($null -ne $encrypted -and $encrypted.ToLower() -eq "true") {
                            $CertificatePassword = ConvertTo-SecureString -String $certPwd -Force
                        }
                        else {
                            $CertificatePassword = ConvertTo-SecureString -String $certPwd -AsPlainText -Force
                        }
                        Write-Info "Using CertificatePassword from configuration.xml"
                    }
                }
            }
        }
        catch {
            Write-Warn "Could not read configuration.xml: $($_.Exception.Message)"
        }
    }
}

# ============================================================================
# Banner
# ============================================================================
Write-Host ""
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "  UCC Site Modernization Tool v$ScriptVersion" -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host ""
Write-Host "  Site: $SiteUrl" -ForegroundColor White
Write-Host "  Mode: $Mode" -ForegroundColor White
Write-Host ""

# ============================================================================
# Load PnP PowerShell
# ============================================================================
# Use bundled PnP.PowerShell module (v3.1.0) for consistent behavior
$pnpModulePath = Join-Path $ScriptDir "bundle\PnP.PowerShell"
if (Test-Path $pnpModulePath) {
    Write-Info "Loading bundled PnP.PowerShell module (v3.1.0)..."
    Import-Module "$pnpModulePath\PnP.PowerShell.psd1" -Force -DisableNameChecking
}
else {
    Write-Err "Bundled PnP.PowerShell module not found at: $pnpModulePath"
    Write-Err "Please ensure the bundle folder is included in the installation package."
    exit 1
}

# ============================================================================
# Validate Authentication Parameters
# ============================================================================
# Note: As of September 9th 2024, the PnP Management Shell multi-tenant app has been deleted.
#       You must register your own Entra ID Application and provide the ClientId.
#       See: https://pnp.github.io/powershell/articles/registerapplication.html
if ($Interactive -and -not $ClientId) {
    Write-Err "ClientId is required for interactive authentication."
    Write-Err ""
    Write-Err "The PnP Management Shell multi-tenant app was deleted on September 9th, 2024."
    Write-Err "You must register your own Entra ID Application and provide the -ClientId parameter."
    Write-Err ""
    Write-Err "See: https://pnp.github.io/powershell/articles/registerapplication.html"
    exit 1
}

# Prompt for certificate password if using certificate auth and password not provided
if ($CertificatePath -and -not $Interactive) {
    if ($null -eq $CertificatePassword) {
        Write-Host ""
        $CertificatePassword = Read-Host -Prompt "Enter certificate password" -AsSecureString
        Write-Host ""
    }
}

# ============================================================================
# Connect to Site
# ============================================================================
Write-Info "Connecting to site..."
try {
    if ($Interactive) {
        Connect-PnPOnline -Url $SiteUrl -Interactive -ClientId $ClientId
    }
    elseif ($CertificatePath) {
        if (-not $ClientId -or -not $Tenant) {
            Write-Err "ClientId and Tenant are required for certificate-based authentication."
            exit 1
        }
        Connect-PnPOnline -Url $SiteUrl -ClientId $ClientId -CertificatePath $CertificatePath -CertificatePassword $CertificatePassword -Tenant $Tenant
    }
    else {
        Write-Err "No authentication method specified. Use -Interactive -ClientId or provide certificate parameters."
        exit 1
    }
    Write-Success "Connected to site"
}
catch {
    Write-Err "Failed to connect: $($_.Exception.Message)"
    exit 1
}

# ============================================================================
# Analyze Site
# ============================================================================
Write-Host ""
Write-Host "------------------------------------------------------------" -ForegroundColor Gray
Write-Host "  Site Analysis" -ForegroundColor White
Write-Host "------------------------------------------------------------" -ForegroundColor Gray

# Check current homepage
$web = Get-PnPWeb -Includes WelcomePage
$currentHomepage = $web.WelcomePage
Write-Info "Current homepage: $currentHomepage"

$isClassicHomepage = $currentHomepage -like "*portal.aspx*" -or $currentHomepage -like "*default.aspx*"
if ($isClassicHomepage) {
    Write-Warn "Classic homepage detected - needs modernization"
}

# Check if Home.aspx exists and has UCC Dashboard
$hasModernHomepage = $false
$hasUccDashboard = $false

try {
    $homePage = Get-PnPPage -Identity "Home" -ErrorAction SilentlyContinue
    if ($homePage) {
        $hasModernHomepage = $true
        Write-Info "Home.aspx exists"
        
        # Check for UCC Dashboard web part
        $webParts = Get-PnPPageComponent -Page "Home" -ErrorAction SilentlyContinue
        $uccWebPart = $webParts | Where-Object { 
            $_.Title -eq "UCC Dashboard" -or $_.WebPartId -eq $uccDashboardComponentId 
        }
        if ($uccWebPart) {
            $hasUccDashboard = $true
            Write-Success "UCC Dashboard web part is present"
        }
        else {
            Write-Warn "UCC Dashboard web part is NOT present on Home.aspx"
        }
    }
    else {
        Write-Warn "Home.aspx does not exist"
    }
}
catch {
    Write-Warn "Could not check Home.aspx: $($_.Exception.Message)"
}

# Check if homepage is set to Home.aspx
$homepageIsHome = $currentHomepage -like "*SitePages/Home.aspx*"
if ($homepageIsHome -and $hasUccDashboard) {
    Write-Success "Homepage is correctly set to Home.aspx with UCC Dashboard"
}

# Detect site type:
# - UCC Site (has Agents list) -> needs UCC Dashboard as homepage
# - Parent/Hub Site (has A365_UCC_Creator but NO Agents list) -> needs list view as homepage
$isParentSite = $false
$isUccSite = $false
$hasAgentsList = $false
$hasCreatorList = $false

# Get all lists and check by title
try {
    $allLists = Get-PnPList -ErrorAction Stop
    $listCount = ($allLists | Measure-Object).Count
    Write-Info "Found $listCount lists on site"
    
    foreach ($list in $allLists) {
        if ($list.Title -eq "Agents") {
            $hasAgentsList = $true
        }
        if ($list.Title -eq "Anywhere365 UCC Creator" -or $list.Title -eq "A365_UCC_Creator") {
            $hasCreatorList = $true
        }
    }
    
    Write-Info "Agents list: $hasAgentsList | A365_UCC_Creator list: $hasCreatorList"
}
catch {
    Write-Warn "Could not retrieve lists: $($_.Exception.Message)"
}

if ($hasAgentsList) {
    # Has Agents list = this is a UCC site (needs UCC Dashboard)
    $isUccSite = $true
    Write-Info "Detected UCC site (Agents list found)"
}
elseif ($hasCreatorList) {
    # Has A365_UCC_Creator but no Agents = parent/hub site
    $isParentSite = $true
    Write-Info "Detected parent site (A365_UCC_Creator list found, no Agents list)"
}
else {
    # Neither Agents nor A365_UCC_Creator list found - this is not a recognized UCC site
    Write-Host ""
    Write-Host "------------------------------------------------------------" -ForegroundColor Gray
    Write-Host "  Site Skipped" -ForegroundColor Yellow
    Write-Host "------------------------------------------------------------" -ForegroundColor Gray
    Write-Host ""
    Write-Warn "This site does not appear to be a UCC site or parent site."
    Write-Info "  - No 'Agents' list found (required for UCC sites)"
    Write-Info "  - No 'A365_UCC_Creator' list found (required for parent sites)"
    Write-Host ""
    Write-Info "The site will not be modified. This could be:"
    Write-Info "  - A custom site added by the customer"
    Write-Info "  - A nested parent site structure"
    Write-Info "  - A site that was not created with UCC Site Creator"
    Write-Host ""
    # Still hide the left navigation even on skipped intermediate sites.
    # Deeply nested UCC subsites inherit navigation from their closest parent,
    # so grouping subsites (e.g. /emea, /apac) must also have QuickLaunch
    # disabled or the UCC subsite beneath them will still show the left nav.
    Write-Info "Hiding left navigation on intermediate site to prevent inheritance by child UCC sites..."
    Invoke-HideLeftNavigation
    Disconnect-PnPOnline -ErrorAction SilentlyContinue
    return @{
        Success = $true
        Skipped = $true
        Message = "Site skipped - not a recognized UCC or parent site"
    }
}

# ============================================================================
# Summary
# ============================================================================
Write-Host ""
Write-Host "------------------------------------------------------------" -ForegroundColor Gray
Write-Host "  Analysis Summary" -ForegroundColor White
Write-Host "------------------------------------------------------------" -ForegroundColor Gray

$needsModernization = $false
if ($isParentSite) {
    # Parent site needs modernization if homepage isn't the UCC Creator list
    $homepageIsCreatorList = $currentHomepage -like "*A365_UCC_Creator*"
    $needsModernization = (-not $homepageIsCreatorList) -or $Force
    if ($homepageIsCreatorList -and -not $Force) {
        Write-Host ""
        Write-Success "Parent site is already modernized (homepage = A365_UCC_Creator)"
        Write-Info "Use -Force to re-run modernization anyway"
        Write-Host ""
        Disconnect-PnPOnline -ErrorAction SilentlyContinue
        exit 0
    }
    elseif ($homepageIsCreatorList -and $Force) {
        Write-Host ""
        Write-Info "Parent site appears modernized, but -Force specified - will re-modernize"
    }
    else {
        Write-Host ""
        Write-Warn "Parent site needs modernization:"
        Write-Host "  - Homepage should be set to A365_UCC_Creator list" -ForegroundColor Yellow
    }
}
else {
    $needsModernization = (-not $hasUccDashboard) -or (-not $homepageIsHome)

    if ($needsModernization) {
        Write-Host ""
        Write-Warn "Site needs modernization:"
        if (-not $hasModernHomepage) {
            Write-Host "  - Home.aspx needs to be created" -ForegroundColor Yellow
        }
        if (-not $hasUccDashboard) {
            Write-Host "  - UCC Dashboard web part needs to be added" -ForegroundColor Yellow
        }
        if (-not $homepageIsHome) {
            Write-Host "  - Homepage needs to be set to Home.aspx" -ForegroundColor Yellow
        }
    }
    else {
        Write-Host ""
        if ($Force) {
            Write-Info "Site appears modernized, but -Force specified - will re-modernize"
        }
        else {
            Write-Success "Site is already modernized!"
            Write-Info "Use -Force to re-run modernization anyway"
            Write-Host ""
            Disconnect-PnPOnline -ErrorAction SilentlyContinue
            exit 0
        }
    }
}

# ============================================================================
# Modernize (if requested)
# ============================================================================
if ($Mode -eq "Analyze") {
    Write-Host ""
    Write-Info "Run with -Mode Modernize to apply changes"
    Write-Host ""
    Disconnect-PnPOnline -ErrorAction SilentlyContinue
    exit 0
}

# Confirm before proceeding
if (-not $Force) {
    Write-Host ""
    $confirm = Read-Host "Proceed with modernization? (y/n)"
    if ($confirm -ne "y" -and $confirm -ne "Y") {
        Write-Info "Modernization cancelled"
        Disconnect-PnPOnline -ErrorAction SilentlyContinue
        exit 0
    }
}

Write-Host ""
Write-Host "------------------------------------------------------------" -ForegroundColor Gray
Write-Host "  Modernizing Site" -ForegroundColor White
Write-Host "------------------------------------------------------------" -ForegroundColor Gray

# Handle parent site differently - set homepage to A365_UCC_Creator list
if ($isParentSite) {
    Write-Info "Parent site detected - configuring for UCC Creator list view..."
    
    # Set homepage to the A365_UCC_Creator list
    try {
        Set-PnPHomePage -RootFolderRelativeUrl "Lists/A365_UCC_Creator/AllItems.aspx" -ErrorAction Stop
        Write-Success "Homepage set to A365_UCC_Creator list"
    }
    catch {
        Write-Warn "Could not set homepage to list: $($_.Exception.Message)"
        Write-Info "Trying alternative homepage path..."
        try {
            Set-PnPHomePage -RootFolderRelativeUrl "Lists/A365_UCC_Creator" -ErrorAction Stop
            Write-Success "Homepage set to A365_UCC_Creator list"
        }
        catch {
            Write-Warn "Could not set homepage: $($_.Exception.Message)"
        }
    }
    
    # Still do the cleanup steps (branding, navigation, etc.)
    # Jump to cleanup section
}
else {

# Create or update Home.aspx with UCC Dashboard

# If using site collection App Catalog, install the SPFx app before creating the page
# (component must be installed on this site for the web part to render)
if ($UseSiteCollectionAppCatalog -or -not [string]::IsNullOrEmpty($SiteCollectionAppCatalogUrl)) {
    Write-Info "Site collection catalog mode - ensuring UCC Dashboard app is installed..."
    try {
        $uccApp = Get-PnPApp -Identity "ucc-dashboard-spfx-client-side-solution" -Scope Site -ErrorAction SilentlyContinue
        if (-not $uccApp) { $uccApp = Get-PnPApp -Identity "26A55D4E-07B7-4ADA-A0B8-0A31A8D2E3C1" -Scope Site -ErrorAction SilentlyContinue }
        if ($uccApp) {
            if ($uccApp.InstalledVersion) {
                Write-Info "  UCC Dashboard app already installed (v$($uccApp.InstalledVersion))"
            } else {
                Write-Info "  Installing UCC Dashboard app..."
                Install-PnPApp -Identity $uccApp.Id -Scope Site -Wait -ErrorAction Stop
                Write-Info "  UCC Dashboard app installed"
            }
        } else {
            Write-Warn "  UCC Dashboard app not found in site collection catalog."
            Write-Warn "  Run Deploy-UccDashboard.ps1 -SiteCollectionAppCatalogUrl first."
            Write-Warn "  Web part may not render without the app installed."
        }
    }
    catch { Write-Warn "  Could not install UCC Dashboard app: $($_.Exception.Message)" }
}

try {
    # For subsites, ensure SitePages feature is enabled
    Write-Info "Ensuring SitePages feature is enabled..."
    try {
        # Enable modern site pages feature (required for subsites)
        Enable-PnPFeature -Identity "B6917CB1-93A0-4B97-A84D-7CF49975D4EC" -Scope Web -Force -ErrorAction SilentlyContinue
    }
    catch {
        # Feature may already be enabled or not applicable
        Write-Info "SitePages feature check completed"
    }
    
    # Ensure SitePages library exists
    $sitePagesLib = $null
    try {
        $sitePagesLib = Get-PnPList -Identity "SitePages" -ErrorAction SilentlyContinue
    }
    catch { }
    
    if ($null -eq $sitePagesLib) {
        Write-Warn "SitePages library not found - this may be a classic subsite"
        Write-Info "Attempting to create SitePages library..."
        try {
            # Try enabling the feature again with different approach
            $web = Get-PnPWeb
            $ctx = Get-PnPContext
            $features = $web.Features
            $ctx.Load($features)
            $ctx.ExecuteQuery()
            
            # Site Pages feature GUID
            $sitePagesFeatureId = [Guid]"B6917CB1-93A0-4B97-A84D-7CF49975D4EC"
            $features.Add($sitePagesFeatureId, $true, [Microsoft.SharePoint.Client.FeatureDefinitionScope]::None)
            $ctx.ExecuteQuery()
            Write-Info "SitePages feature activated"
        }
        catch {
            Write-Warn "Could not activate SitePages feature: $($_.Exception.Message)"
        }
    }
    
    # Remove existing Home.aspx to ensure clean layout
    Write-Info "Removing existing Home.aspx for fresh layout..."
    $homePageRemoved = $false
    
    # First, temporarily set a different homepage so Home.aspx can be deleted
    try {
        $tempPage = Add-PnPPage -Name "TempHomePage" -LayoutType Article -Title "Temporary" -Publish -ErrorAction SilentlyContinue
        if ($tempPage) {
            Set-PnPHomePage -RootFolderRelativeUrl "SitePages/TempHomePage.aspx" -ErrorAction Stop
            Start-Sleep -Seconds 2
        }
    }
    catch { }
    
    try {
        Remove-PnPPage -Identity "Home" -Force -ErrorAction Stop
        Write-Info "Home.aspx removed"
        $homePageRemoved = $true
    }
    catch {
        # Remove-PnPPage failed — delete via CSOM list item (bypasses welcome page lock)
        try {
            $existingPage = Get-PnPListItem -List "SitePages" -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>Home.aspx</Value></Eq></Where></Query></View>" -ErrorAction SilentlyContinue
            if ($existingPage) {
                Remove-PnPListItem -List "SitePages" -Identity $existingPage.Id -Force -Recycle -ErrorAction Stop | Out-Null
                Write-Info "Home.aspx removed (via list item)"
                $homePageRemoved = $true
            }
            else {
                $homePageRemoved = $true  # Page doesn't exist, nothing to remove
            }
        }
        catch {
            Write-Warn "Could not remove existing Home.aspx: $($_.Exception.Message)"
            Write-Info "Will update existing page instead"
        }
    }
    
    # Small delay to ensure SharePoint processes the deletion
    Start-Sleep -Seconds 2
    
    # Create Home.aspx (or update existing if removal failed)
    Write-Info "Creating Home.aspx..."
    $homePage = $null
    $pageAlreadyExists = $false
    
    try {
        $homePage = Add-PnPPage -Name "Home" -LayoutType Home -Title "UCC Dashboard" -ErrorAction Stop
    }
    catch {
        # Page might already exist - try to get it and clear it
        Write-Info "Trying alternative page creation method..."
        try {
            if (-not $homePageRemoved) {
                # Page exists, we need to clear its content
                $homePage = Get-PnPPage -Identity "Home" -ErrorAction SilentlyContinue
                if ($homePage) {
                    Write-Info "Clearing existing Home.aspx content..."
                    $pageAlreadyExists = $true
                    
                    # Get all web parts on the page and remove them
                    try {
                        $webParts = Get-PnPPageComponent -Page "Home" -ErrorAction SilentlyContinue
                        foreach ($wp in $webParts) {
                            Remove-PnPPageComponent -Page "Home" -InstanceId $wp.InstanceId -Force -ErrorAction SilentlyContinue
                        }
                        Write-Info "Cleared existing web parts"
                    }
                    catch { }
                    
                    # Clear sections by setting page to blank layout then re-save
                    try {
                        # Save the cleared page
                        Set-PnPPage -Identity "Home" -LayoutType Home -Title "UCC Dashboard" -ErrorAction SilentlyContinue | Out-Null
                    }
                    catch { }
                }
            }
            else {
                # Create using Article layout which works better on subsites
                $homePage = Add-PnPPage -Name "Home" -LayoutType Article -Title "UCC Dashboard" -ErrorAction Stop
            }
        }
        catch {
            # Last resort - just work with existing page
            $homePage = Get-PnPPage -Identity "Home" -ErrorAction SilentlyContinue
            $pageAlreadyExists = $true
            if (-not $homePage) {
                throw "Could not create or access Home.aspx: $($_.Exception.Message)"
            }
        }
    }
    
    # Clean up temporary page
    try {
        Remove-PnPPage -Identity "TempHomePage" -Force -ErrorAction SilentlyContinue
    }
    catch { }
    
    # Add full-width section and UCC Dashboard web part
    Write-Info "Adding UCC Dashboard web part (full-width)..."
    $webPartAdded = $false
    $fullWidthDone = $false
    
    # If page already exists, we need to handle it differently
    if ($pageAlreadyExists) {
        # For existing pages, try to add web part directly (section may already exist)
        try {
            # First try adding to existing section
            Add-PnPPageWebPart -Page "Home" -Component "UCC Dashboard" -Section 1 -Column 1 -ErrorAction Stop | Out-Null
            $webPartAdded = $true
            Write-Success "UCC Dashboard web part added to existing section"
        }
        catch {
            # Try without section specification
            try {
                Add-PnPPageWebPart -Page "Home" -Component "UCC Dashboard" -ErrorAction Stop | Out-Null
                $webPartAdded = $true
                Write-Success "UCC Dashboard web part added"
            }
            catch {
                Write-Warn "Could not add web part to existing page: $($_.Exception.Message)"
                Write-Info "The page already has the UCC Dashboard - no changes needed"
                $webPartAdded = $true  # Assume it's already there
            }
        }
    }
    else {
        # New page - add full-width section first
        try {
            # Add full-width section first
            Add-PnPPageSection -Page "Home" -SectionTemplate OneColumnFullWidth -Order 1 -ErrorAction Stop | Out-Null
            # Add web part to full-width section
            Add-PnPPageWebPart -Page "Home" -Component "UCC Dashboard" -Section 1 -Column 1 -ErrorAction Stop | Out-Null
            $webPartAdded = $true
            $fullWidthDone = $true
            Write-Success "UCC Dashboard web part added (full-width)"
        }
        catch {
            # Full-width section not supported via PnP (common on classic subsites)
            Write-Info "Full-width section not supported via PnP, adding to regular section..."
            try {
                Add-PnPPageWebPart -Page "Home" -Component "UCC Dashboard" -ErrorAction Stop | Out-Null
                $webPartAdded = $true
            }
            catch {
                try {
                    Add-PnPPageWebPart -Page "Home" -Component $uccDashboardComponentId -ErrorAction Stop | Out-Null
                    $webPartAdded = $true
                }
                catch {
                    Write-Err "Could not add UCC Dashboard web part: $($_.Exception.Message)"
                    Write-Err "Ensure ucc-dashboard-spfx.sppkg is deployed tenant-wide (run Deploy-UccDashboard.ps1)"
                    Disconnect-PnPOnline -ErrorAction SilentlyContinue
                    exit 1
                }
            }
            if ($webPartAdded) {
                Write-Success "UCC Dashboard web part added"
            }
        }
    }
    
    # After adding the web part, try to promote to full-width via CSOM if not already done
    if ($webPartAdded -and -not $fullWidthDone) {
        try {
            Write-Info "Promoting section to full-width via CSOM..."
            $pageItem = Get-PnPListItem -List "SitePages" -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>Home.aspx</Value></Eq></Where></Query></View>" -ErrorAction Stop
            
            if ($pageItem) {
                $canvasContent = $pageItem.FieldValues["CanvasContent1"]
                
                if ($canvasContent) {
                    # Replace the section control data to use full-width
                    # controlType 0 = section, sectionType 1 = OneColumn, 3 = OneColumnFullWidth
                    # Also change sectionFactor from 12 to 0 for full-width and layoutIndex to 2
                    $updatedCanvas = $canvasContent
                    
                    # Method 1: Update the position data in web part controls
                    # Change layoutIndex from 1 to 2 (full-width indicator)
                    $updatedCanvas = $updatedCanvas -replace '"layoutIndex":1', '"layoutIndex":2'
                    
                    # Method 2: Update section emphasis data if present
                    # Add isFullWidth flag
                    $updatedCanvas = $updatedCanvas -replace '"zoneEmphasis":0\}', '"zoneEmphasis":0,"isFullWidth":true}'
                    
                    if ($updatedCanvas -ne $canvasContent) {
                        $pageItem["CanvasContent1"] = $updatedCanvas
                        $pageItem.Update()
                        Invoke-PnPQuery -ErrorAction SilentlyContinue
                        Write-Success "Section promoted to full-width"
                    }
                    else {
                        Write-Info "Canvas content unchanged - section may already be full-width"
                    }
                }
            }
        }
        catch {
            Write-Info "Could not promote to full-width: $($_.Exception.Message)"
            Write-Info "Dashboard will display in standard column width"
        }
    }
    
    # Publish the page
    if ($webPartAdded) {
        $publishSuccess = $false
        # Try primary method: Set-PnPPage -Publish
        try {
            Set-PnPPage -Identity "Home" -Publish -ErrorAction Stop | Out-Null
            Write-Success "Home.aspx published"
            $publishSuccess = $true
        }
        catch {
            # Primary method failed, try CSOM approach
            try {
                $pageItem = Get-PnPListItem -List "SitePages" -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>Home.aspx</Value></Eq></Where></Query></View>" -ErrorAction Stop
                if ($pageItem) {
                    $pageItem.File.Publish("Published by UCC Site Creator")
                    Invoke-PnPQuery -ErrorAction Stop
                    Write-Success "Home.aspx published (via CSOM)"
                    $publishSuccess = $true
                }
            }
            catch {
                # CSOM also failed - that's OK, page is still in draft
            }
        }
        if (-not $publishSuccess) {
            Write-Info "Page saved as draft - please click Publish in SharePoint UI"
            Write-Info "The web part is ready in full-width layout"
        }
    }
}
catch {
    $publishError = $_.Exception.Message
    Write-Warn "Page publish issue: $publishError"

    # Detect fatal SitePages library schema corruption (missing Title column or similar).
    # This means Home.aspx was never created successfully. Setting it as homepage would
    # leave the site in a broken "Sorry, something went wrong" state in the browser.
    $isFatalSchemaError = (
        $publishError -match "Column 'Title' does not exist" -or
        $publishError -match "Column.*does not exist" -or
        $publishError -match "Invalid field name" -or
        $publishError -match "cannot be found"
    )

    if ($isFatalSchemaError) {
        Write-Host ""
        Write-Host "------------------------------------------------------------" -ForegroundColor Red
        Write-Host "  FATAL: SitePages Library Schema Error" -ForegroundColor Red
        Write-Host "------------------------------------------------------------" -ForegroundColor Red
        Write-Host ""
        Write-Err "Home.aspx could not be created due to a corrupt or incomplete SitePages"
        Write-Err "library schema on this site. Setting it as homepage would cause a"
        Write-Err "'Sorry, something went wrong' error when users navigate to the site."
        Write-Host ""
        Write-Warn "This is a pre-existing issue on the site, not caused by this script."
        Write-Host ""
        Write-Info "To repair, run the following against this site and then re-run this script:"
        Write-Info "  Disable-PnPFeature -Identity 'B6917CB1-93A0-4B97-A84D-7CF49975D4EC' -Force"
        Write-Info "  Enable-PnPFeature  -Identity 'B6917CB1-93A0-4B97-A84D-7CF49975D4EC' -Force"
        Write-Info "This reactivates the SitePages feature and rebuilds the library schema."
        Write-Host ""
        Disconnect-PnPOnline -ErrorAction SilentlyContinue
        return @{
            Success = $false
            Skipped = $false
            Error   = "SitePages library schema corrupt - Column 'Title' missing. Run SitePages feature repair then retry."
        }
    }

    Write-Info "Continuing to set homepage..."
}

# Validate Home.aspx actually exists before setting as homepage.
# If page creation silently failed (non-fatal publish error), setting a missing
# page as homepage causes a browser-side "Sorry, something went wrong" error.
Write-Info "Validating Home.aspx was created successfully..."
$homePageValid = $false
# Retry up to 3 times with a short wait — draft-saved pages can take a moment to appear
for ($attempt = 1; $attempt -le 3; $attempt++) {
    try {
        # Use "SitePages" (no space) — the internal list name, not the display title
        $homePageCheck = Get-PnPListItem `
            -List "SitePages" `
            -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>Home.aspx</Value></Eq></Where></Query></View>" `
            -ErrorAction SilentlyContinue
        if ($homePageCheck) {
            $homePageValid = $true
            Write-Info "Home.aspx verified in SitePages library"
            break
        }
    }
    catch { }
    if ($attempt -lt 3) {
        Write-Info "Home.aspx not yet visible — retrying ($attempt / 3)..."
        Start-Sleep -Seconds 3
    }
}
if (-not $homePageValid) {
    Write-Warn "Home.aspx not found in SitePages library after creation attempt"
}

if (-not $homePageValid) {
    Write-Host ""
    Write-Host "------------------------------------------------------------" -ForegroundColor Red
    Write-Host "  FATAL: Home.aspx Was Not Created" -ForegroundColor Red
    Write-Host "------------------------------------------------------------" -ForegroundColor Red
    Write-Host ""
    Write-Err "Home.aspx does not exist in the SitePages library after all creation attempts."
    Write-Err "Setting it as homepage would cause a 'Sorry, something went wrong' error."
    Write-Host ""
    Write-Info "Possible causes:"
    Write-Info "  - SitePages library schema is corrupt (missing columns)"
    Write-Info "  - SitePages feature was not active and could not be enabled"
    Write-Info "  - Insufficient permissions on the SitePages library"
    Write-Host ""
    Write-Info "To repair:"
    Write-Info "  1. Check the SitePages library at: $SiteUrl/_layouts/15/listedit.aspx?List=SitePages"
    Write-Info "  2. Run: Disable-PnPFeature -Identity 'B6917CB1-93A0-4B97-A84D-7CF49975D4EC' -Force"
    Write-Info "         Enable-PnPFeature  -Identity 'B6917CB1-93A0-4B97-A84D-7CF49975D4EC' -Force"
    Write-Info "  3. Re-run this script with -Force"
    Write-Host ""
    Disconnect-PnPOnline -ErrorAction SilentlyContinue
    return @{
        Success = $false
        Skipped = $false
        Error   = "Home.aspx not found in SitePages library after all creation attempts. SitePages feature repair required."
    }
}

# Set Home.aspx as homepage (only reached if Home.aspx was verified above)
try {
    Write-Info "Setting Home.aspx as homepage..."
    Set-PnPHomePage -RootFolderRelativeUrl "SitePages/Home.aspx"
    Write-Success "Homepage set to Home.aspx"
}
catch {
    Write-Warn "Could not set homepage: $($_.Exception.Message)"
}

} # end else (not parent site) - UCC subsite modernization

# ============================================================================
# Cleanup (applies to both parent sites and subsites)
# ============================================================================

# Clean up legacy portal pages
Write-Info "Cleaning up legacy portal pages..."
$legacyPages = @("ivrgfx.aspx", "portal.aspx", "ivrfgx.aspx")
foreach ($legacyPage in $legacyPages) {
    try {
        # Try to remove from SitePages
        $page = Get-PnPListItem -List "SitePages" -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>$legacyPage</Value></Eq></Where></Query></View>" -ErrorAction SilentlyContinue
        if ($page) {
            Remove-PnPListItem -List "SitePages" -Identity $page.Id -Force -ErrorAction SilentlyContinue
            Write-Info "Removed $legacyPage from Site Pages"
        }
    }
    catch { }
    try {
        # Try to remove from Pages library (classic)
        $page = Get-PnPListItem -List "Pages" -Query "<View><Query><Where><Eq><FieldRef Name='FileLeafRef'/><Value Type='Text'>$legacyPage</Value></Eq></Where></Query></View>" -ErrorAction SilentlyContinue
        if ($page) {
            Remove-PnPListItem -List "Pages" -Identity $page.Id -Force -ErrorAction SilentlyContinue
            Write-Info "Removed $legacyPage from Pages"
        }
    }
    catch { }
}

# Remove navigation nodes that link to legacy pages
Write-Info "Cleaning up navigation nodes..."
try {
    $navNodes = Get-PnPNavigationNode -Location QuickLaunch -ErrorAction SilentlyContinue
    foreach ($node in $navNodes) {
        if ($node.Url -match "ivrgfx|portal\.aspx|ivrfgx") {
            Remove-PnPNavigationNode -Identity $node.Id -Force -ErrorAction SilentlyContinue
            Write-Info "Removed navigation node: $($node.Title)"
        }
    }
    # Also check top navigation
    $topNavNodes = Get-PnPNavigationNode -Location TopNavigationBar -ErrorAction SilentlyContinue
    foreach ($node in $topNavNodes) {
        if ($node.Url -match "ivrgfx|portal\.aspx|ivrfgx") {
            Remove-PnPNavigationNode -Identity $node.Id -Force -ErrorAction SilentlyContinue
            Write-Info "Removed top navigation node: $($node.Title)"
        }
    }
}
catch {
    Write-Warn "Could not clean navigation nodes: $($_.Exception.Message)"
}

# Clear site logo URL if it points to legacy page
try {
    $web = Get-PnPWeb -Includes SiteLogoUrl -ErrorAction SilentlyContinue
    if ($web.SiteLogoUrl -match "ivrgfx|portal\.aspx") {
        Write-Info "Clearing legacy site logo URL..."
        $web.SiteLogoUrl = ""
        $web.Update()
        Invoke-PnPQuery -ErrorAction SilentlyContinue
        Write-Info "Site logo URL cleared"
    }
}
catch { }

# Clear property bag entries that might reference legacy pages
Write-Info "Cleaning up property bag entries..."
try {
    $propertyBagKeys = @(
        "vti_welcomepage",
        "vti_defaultredirectpage",
        "__NavigationOrderingDefault"
    )
    foreach ($key in $propertyBagKeys) {
        try {
            $value = Get-PnPPropertyBag -Key $key -ErrorAction SilentlyContinue
            if ($value -match "ivrgfx|portal\.aspx|ivrfgx") {
                Set-PnPPropertyBagValue -Key $key -Value "SitePages/Home.aspx" -Confirm:$false -ErrorAction SilentlyContinue
                Write-Info "Updated property bag: $key"
            }
        }
        catch { }
    }
}
catch { }

# Clear any custom header link (AlternateCssUrl, CustomMasterUrl might reference legacy pages)
try {
    $web = Get-PnPWeb -Includes AlternateCssUrl, CustomMasterUrl, MasterUrl -ErrorAction SilentlyContinue
    $changed = $false
    
    if ($web.AlternateCssUrl -match "ivrgfx|portal|Anywhere365") {
        $web.AlternateCssUrl = ""
        $changed = $true
        Write-Info "Cleared AlternateCssUrl"
    }
    
    if ($changed) {
        $web.Update()
        Invoke-PnPQuery -ErrorAction SilentlyContinue
    }
}
catch { }

# Remove the header link/title link that shows ivrgfx.aspx
# This is injected via ScriptLink custom actions from the Anywhere365 branding
if ($PreserveLegacyScripts) {
    Write-Info "Preserving legacy scripts (-PreserveLegacyScripts specified)"
    Write-Info "Note: Run again without -PreserveLegacyScripts after all sites are modernized to complete cleanup"
}
else {
    Write-Info "Removing custom branding scripts..."
    try {
        # Check for custom actions that inject JavaScript (ScriptLink location)
        $customActions = Get-PnPCustomAction -Scope Web -ErrorAction SilentlyContinue
        foreach ($action in $customActions) {
            # Remove any ScriptLink custom actions - these inject the Anywhere365 header
            if ($action.Location -eq "ScriptLink") {
                Remove-PnPCustomAction -Identity $action.Id -Scope Web -Force -ErrorAction SilentlyContinue
                Write-Info "Removed ScriptLink custom action: $($action.Name)"
            }
        }
        
        # Also check site collection level custom actions
        $siteCustomActions = Get-PnPCustomAction -Scope Site -ErrorAction SilentlyContinue
        foreach ($action in $siteCustomActions) {
            if ($action.Location -eq "ScriptLink") {
                Remove-PnPCustomAction -Identity $action.Id -Scope Site -Force -ErrorAction SilentlyContinue
                Write-Info "Removed site collection ScriptLink custom action: $($action.Name)"
            }
        }
    }
    catch {
        Write-Warn "Could not remove custom actions: $($_.Exception.Message)"
    }
}

# Try to deactivate Anywhere365 related features
Write-Info "Checking for Anywhere365 features..."
try {
    $features = Get-PnPFeature -Scope Web -ErrorAction SilentlyContinue
    foreach ($feature in $features) {
        if ($feature.DisplayName -match "Anywhere|UCC|365") {
            try {
                Disable-PnPFeature -Identity $feature.DefinitionId -Scope Web -Force -ErrorAction SilentlyContinue
                Write-Info "Deactivated web feature: $($feature.DisplayName)"
            }
            catch { }
        }
    }
    
    $siteFeatures = Get-PnPFeature -Scope Site -ErrorAction SilentlyContinue
    foreach ($feature in $siteFeatures) {
        if ($feature.DisplayName -match "Anywhere|UCC|365") {
            try {
                Disable-PnPFeature -Identity $feature.DefinitionId -Scope Site -Force -ErrorAction SilentlyContinue
                Write-Info "Deactivated site collection feature: $($feature.DisplayName)"
            }
            catch { }
        }
    }
}
catch { }

# Clear the custom JavaScript link property bag entries that Anywhere365 uses
try {
    $jsPropertyKeys = @(
        "JavaScriptLink",
        "vti_JSUrl", 
        "wsp_ucc_JavaScriptLink"
    )
    foreach ($key in $jsPropertyKeys) {
        try {
            $value = Get-PnPPropertyBag -Key $key -ErrorAction SilentlyContinue
            if ($value) {
                Remove-PnPPropertyBagValue -Key $key -ErrorAction SilentlyContinue
                Write-Info "Removed property bag: $key"
            }
        }
        catch { }
    }
}
catch { }



Invoke-HideLeftNavigation


# ============================================================================
# Schema Updates (add missing columns to lists)
# ============================================================================
Write-Info "Checking for schema updates..."
try {
    # Load the schema updates module
    $schemaUpdatesPath = Join-Path $PSScriptRoot "SchemaUpdates.ps1"
    if (Test-Path $schemaUpdatesPath) {
        . $schemaUpdatesPath
        
        $schemaResult = Invoke-SchemaUpdates
        
        $schemaChanged = $schemaResult.ColumnsAdded -gt 0 -or $schemaResult.ItemsAdded -gt 0
        if ($schemaChanged) {
            $colMsg = if ($schemaResult.ColumnsAdded -gt 0) { "$($schemaResult.ColumnsAdded) column(s) added" } else { $null }
            $itemMsg = if ($schemaResult.ItemsAdded -gt 0) { "$($schemaResult.ItemsAdded) item(s) added" } else { $null }
            $parts = @($colMsg, $itemMsg) | Where-Object { $_ }
            Write-Success "Schema updated: $($parts -join ', ') to $($schemaResult.ListsUpdated -join ', ')"
        }
        else {
            Write-Info "Schema is up to date"
        }
    }
}
catch {
    Write-Warn "Schema update check failed: $($_.Exception.Message)"
}

# ============================================================================
# Disable page comments
# ============================================================================
Write-Info "Disabling page comments..."
try {
    # Check if this is a subsite
    $currentWeb = Get-PnPWeb -Includes ServerRelativeUrl
    $currentSite = Get-PnPSite -Includes ServerRelativeUrl
    $isSubsite = $currentWeb.ServerRelativeUrl -ne $currentSite.ServerRelativeUrl
    
    if ($isSubsite) {
        # For subsites, disable comments on the Home.aspx page specifically
        # Site-wide setting only works at site collection root
        try {
            $ctx = Get-PnPContext
            $pageFile = $ctx.Web.GetFileByServerRelativeUrl("$($currentWeb.ServerRelativeUrl)/SitePages/Home.aspx")
            $listItem = $pageFile.ListItemAllFields
            $ctx.Load($listItem)
            $ctx.ExecuteQuery()
            
            # Set CommentsDisabled field on the page
            $listItem["CommentsDisabled"] = $true
            $listItem.Update()
            $ctx.ExecuteQuery()
            Write-Info "Page comments disabled on Home.aspx"
        }
        catch {
            # Non-critical - comments on subsite pages may already be controlled by parent
            Write-Info "Page-level comment setting not applied (subsite inherits from parent)"
        }
    }
    else {
        # For site collections, use site-wide setting
        Set-PnPSite -CommentsOnSitePagesDisabled:$true -ErrorAction Stop
        Write-Info "Page comments disabled"
    }
}
catch {
    Write-Warn "Could not disable page comments: $($_.Exception.Message)"
}

# ============================================================================
# Complete
# ============================================================================
Write-Host ""
Write-Host "============================================================" -ForegroundColor Green
Write-Host "  Modernization Complete!" -ForegroundColor Green
Write-Host "============================================================" -ForegroundColor Green
Write-Host ""
Write-Host "  Site: $SiteUrl" -ForegroundColor White
if ($isParentSite) {
    Write-Host "  Homepage: Lists/A365_UCC_Creator" -ForegroundColor White
    Write-Host "  Type: Parent site (UCC Creator)" -ForegroundColor White
}
else {
    Write-Host "  Homepage: SitePages/Home.aspx" -ForegroundColor White
    Write-Host "  Type: UCC site" -ForegroundColor White
}
Write-Host ""
Write-Host "  Notes:" -ForegroundColor Gray
Write-Host "  - Clear browser cache or use InPrivate to see all changes" -ForegroundColor Gray
Write-Host ""

Disconnect-PnPOnline -ErrorAction SilentlyContinue
