<#
.SYNOPSIS
    Migrates classic AnywhereNow/Anywhere365 UCC sites to MC1117115 compliant modern sites.

.DESCRIPTION
    This script modernizes existing UCC sites by:
    - Adding modern SPFx components
    - Adding the UCC Dashboard web part to a modern page
    - Setting the modern page as the homepage
    
    For subsites, it can export data and create new site collections.

.PARAMETER SiteUrl
    The URL of the UCC site to migrate (can be a site collection or subsite)

.PARAMETER Mode
    Migration mode:
    - Analyze: Only analyze the site, report what needs migration
    - InPlace: Modernize in place (for site collections)
    - Export: Export data for migration to new site
    - Full: Full migration (export, create new site, import)

.PARAMETER TargetUrl
    For Full mode: URL for the new site collection (required for subsite migrations)

.PARAMETER Interactive
    Use interactive browser-based authentication

.PARAMETER ClientId
    Azure AD App Client ID for interactive auth

.EXAMPLE
    # Analyze a site
    .\Migrate-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode Analyze -Interactive -ClientId "your-client-id"

.EXAMPLE
    # In-place modernization of a site collection
    .\Migrate-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc" -Mode InPlace -Interactive -ClientId "your-client-id"

.EXAMPLE
    # Full migration of a subsite to new site collection
    .\Migrate-UccSite.ps1 -SiteUrl "https://contoso.sharepoint.com/sites/ucc/subsite1" -Mode Full -TargetUrl "https://contoso.sharepoint.com/sites/ucc-subsite1" -Interactive -ClientId "your-client-id"
#>

param(
    [Parameter(Mandatory=$true)]
    [string]$SiteUrl,
    
    [Parameter(Mandatory=$true)]
    [ValidateSet("Analyze", "InPlace", "Export", "Full")]
    [string]$Mode,
    
    [string]$TargetUrl,
    
    [switch]$Interactive,
    
    [string]$ClientId,
    
    [string]$ExportPath
)

$ErrorActionPreference = "Stop"

# Script version
$ScriptVersion = "8.4.1.8"

# Script directory
$ScriptDir = $PSScriptRoot
if ([string]::IsNullOrEmpty($ScriptDir)) {
    $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
}

Write-Host ""
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "  AnywhereNow UCC - Site Migration Tool v$ScriptVersion" -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host ""

# Import PnP module
$pnpModulePath = Join-Path $ScriptDir "bundle\PnP.PowerShell\PnP.PowerShell.psd1"
if (Test-Path $pnpModulePath) {
    Import-Module $pnpModulePath -Force -ErrorAction SilentlyContinue
}
if (-not (Get-Module PnP.PowerShell -ErrorAction SilentlyContinue)) {
    Import-Module PnP.PowerShell -Force -ErrorAction Stop
}

# UCC Lists for migration analysis
$uccLists = @(
    "Agents", "Skills", "Endpoints", "Routing", "Businesshours", "Holidays",
    "IVRQuestions", "OutboundDialerCalls", "Playlists", "PluginFlowSettings",
    "PluginSettings", "PluginAttributes", "Settings", "SettingValues", "settingsList",
    "Supervisors", "SkillsPerAgent", "VoicemailAgents", "CallClassifications",
    "CallSummary", "ReasonCodes", "PromptsConfig", "QualityMonitorConfig",
    "Modalities", "CannedResponses", "EncryptedTokens", "Version"
)


# Helper functions
function Write-Info($message) { Write-Host "Info : $message" -ForegroundColor Cyan }
function Write-Success($message) { Write-Host "Success : $message" -ForegroundColor Green }
function Write-Warn($message) { Write-Host "Warning : $message" -ForegroundColor Yellow }
function Write-Err($message) { Write-Host "Error : $message" -ForegroundColor Red }

function Connect-ToSite {
    param([string]$Url)
    
    try {
        if ($Interactive -and $ClientId) {
            Connect-PnPOnline -Url $Url -Interactive -ClientId $ClientId
        } else {
            Connect-PnPOnline -Url $Url -Interactive
        }
        return $true
    } catch {
        Write-Err "Failed to connect to $Url : $($_.Exception.Message)"
        return $false
    }
}

function Get-SiteAnalysis {
    param([string]$Url)
    
    Write-Info "Analyzing site: $Url"
    Write-Host ""
    
    $analysis = @{
        Url = $Url
        IsSubsite = $false
        HasClassicFeatures = $false
        HasCustomScript = $false
        HasPublishingFeatures = $false
        UccListsFound = @()
        UccListsMissing = @()
        TotalItems = 0
        HasClassicHomepage = $false
        CurrentHomepage = ""
        NeedsModernization = @()
        AlreadyModernized = @()
    }
    
    # Check if subsite
    $web = Get-PnPWeb -Includes ServerRelativeUrl, Url
    $site = Get-PnPSite -Includes ServerRelativeUrl, Url
    $analysis.IsSubsite = $web.ServerRelativeUrl -ne $site.ServerRelativeUrl
    
    Write-Info "Site Type: $(if ($analysis.IsSubsite) { 'Subsite' } else { 'Site Collection Root' })"
    
    # Check for Custom Script
    try {
        $denyAddAndCustomizePages = Get-PnPPropertyBag -Key "vti_denyaddandcustomizepages"
        $analysis.HasCustomScript = ($denyAddAndCustomizePages -eq "0")
        Write-Info "Custom Script: $(if ($analysis.HasCustomScript) { 'Enabled' } else { 'Disabled' })"
    } catch { }
    
    # Check for publishing features
    try {
        $publishingFeature = Get-PnPFeature -Scope Web -Identity "94c94ca6-b32f-4da9-a9e3-1f3d343d7ecb" -ErrorAction SilentlyContinue
        $analysis.HasPublishingFeatures = $publishingFeature -ne $null
        Write-Info "Publishing Features: $(if ($analysis.HasPublishingFeatures) { 'Active' } else { 'Not Active' })"
    } catch { }
    
    # Check homepage
    try {
        $analysis.CurrentHomepage = Get-PnPHomePage
        $analysis.HasClassicHomepage = $analysis.CurrentHomepage -like "*portal.aspx*"
        Write-Info "Current Homepage: $($analysis.CurrentHomepage)"
        if ($analysis.HasClassicHomepage) {
            Write-Warn "Classic portal.aspx detected as homepage"
        }
    } catch { }
    
    # Check UCC lists
    Write-Host ""
    Write-Info "Checking UCC Lists..."
    $allLists = Get-PnPList
    
    foreach ($listName in $uccLists) {
        $list = $allLists | Where-Object { $_.Title -eq $listName }
        if ($list) {
            $analysis.UccListsFound += $listName
            
            # Get item count
            $itemCount = $list.ItemCount
            $analysis.TotalItems += $itemCount
            
            # Just track that the list exists - modernization is determined by homepage
            $analysis.AlreadyModernized += $listName
            Write-Host "  [OK] $listName ($itemCount items)" -ForegroundColor Green
        } else {
            $analysis.UccListsMissing += $listName
        }
    }
    
    # Summary
    Write-Host ""
    Write-Info "=== Analysis Summary ==="
    Write-Info "UCC Lists Found: $($analysis.UccListsFound.Count) / $($uccLists.Count)"
    Write-Info "Total Items: $($analysis.TotalItems)"
    Write-Info "Lists Needing Modern SPFxs: $($analysis.NeedsModernization.Count)"
    Write-Info "Lists Already Modernized: $($analysis.AlreadyModernized.Count)"
    
    if ($analysis.IsSubsite) {
        Write-Warn "This is a SUBSITE. For full MC1117115 compliance, consider migrating to a new site collection."
    }
    
    if ($analysis.HasClassicHomepage) {
        Write-Warn "Classic portal.aspx homepage needs to be replaced with SPFx UCC Dashboard"
    }
    
    $analysis.HasClassicFeatures = $analysis.HasCustomScript -or $analysis.HasPublishingFeatures -or $analysis.HasClassicHomepage
    
    return $analysis
}

function Invoke-InPlaceModernization {
    param([string]$Url)
    
    Write-Host ""
    Write-Info "=== In-Place Modernization ==="
    Write-Info "Site: $Url"
    Write-Host ""
    
    # Step 1: Register Modern SPFxs
    Write-Info "Step 1: Registering Modern SPFxs..."
    
    $spfxScript = Join-Path $ScriptDir "SPFx\Deploy-UccSpfx.ps1"
    if (Test-Path $spfxScript) {
        $spfxArgs = @{
            SiteUrl = $Url
        }
        if ($Interactive -and $ClientId) {
            $spfxArgs.Interactive = $true
            $spfxArgs.ClientId = $ClientId
        }
        
        try {
            & $spfxScript @spfxArgs
            Write-Success "SPFx package configured"
        } catch {
            Write-Warn "SPFx deployment script returned: $($_.Exception.Message)"
        }
    } else {
        Write-Info "SPFx package should be deployed tenant-wide via Deploy-UccDashboard.ps1"
        Write-Info "Proceeding with homepage modernization..."
    }
    
    # Step 2: Create/Update modern homepage
    Write-Host ""
    Write-Info "Step 2: Configuring modern homepage..."
    
    try {
        # First check if Site Pages library exists
        $sitePagesLib = Get-PnPList -Identity "Site Pages" -ErrorAction SilentlyContinue
        
        if (-not $sitePagesLib) {
            # Try to enable the SitePages feature for classic sites
            Write-Info "Enabling Site Pages feature..."
            try {
                Enable-PnPFeature -Identity "B6917CB1-93A0-4B97-A84D-7CF49975D4EC" -Scope Web -Force -ErrorAction SilentlyContinue
                Start-Sleep -Seconds 3
                $sitePagesLib = Get-PnPList -Identity "Site Pages" -ErrorAction SilentlyContinue
            } catch {
                Write-Warn "Could not enable Site Pages feature"
            }
        }
        
        if (-not $sitePagesLib) {
            Write-Warn "Site Pages library not available - skipping modern homepage"
            Write-Info "Modern homepage will be configured"
        } else {
            # Check if Home.aspx exists
            $homePage = Get-PnPPage -Identity "Home" -ErrorAction SilentlyContinue
            if (-not $homePage) {
                Write-Info "Creating Home.aspx..."
                try {
                    $homePage = Add-PnPPage -Name "Home" -LayoutType Home -Title "UCC Dashboard" -ErrorAction Stop
                    Start-Sleep -Seconds 3
                } catch {
                    Write-Warn "Could not create modern Home page: $($_.Exception.Message)"
                    Write-Info "Modern homepage will be configured"
                }
            }
            
            if ($homePage -or (Get-PnPPage -Identity "Home" -ErrorAction SilentlyContinue)) {
                # Check if UCC Dashboard web part exists
                $existingWebParts = Get-PnPPageComponent -Page "Home" -ErrorAction SilentlyContinue
                $hasUccPortal = ($existingWebParts | Where-Object { $_.Title -eq "UCC Dashboard" }) -ne $null
                
                if (-not $hasUccPortal) {
                    Write-Info "Adding UCC Dashboard web part..."
                    try {
                        Add-PnPPageWebPart -Page "Home" -Component "UCC Dashboard" -ErrorAction Stop
                        Set-PnPPage -Identity "Home" -Publish
                        Write-Success "UCC Dashboard web part added"
                    } catch {
                        Write-Warn "Could not add UCC Dashboard web part (may not be deployed tenant-wide yet)"
                        Write-Warn "Run Deploy-UccDashboard.ps1 on the tenant first"
                    }
                } else {
                    Write-Info "UCC Dashboard web part already exists"
                }
                
                # Set as homepage
                Set-PnPHomePage -RootFolderRelativeUrl "SitePages/Home.aspx"
                Write-Success "Homepage set to SitePages/Home.aspx"
            }
        }
        
    } catch {
        Write-Err "Failed to configure homepage: $($_.Exception.Message)"
    }
    
    Write-Host ""
    Write-Success "=== In-Place Modernization Complete ==="
    Write-Info "Site URL: $Url"
    Write-Host ""
    Write-Info "Next steps:"
    Write-Info "1. Verify the site works correctly"
    Write-Info "2. Test creating/editing items in lists"
    Write-Info "3. Consider disabling Custom Script if not needed"
}

function Export-UccSiteData {
    param(
        [string]$Url,
        [string]$OutputPath
    )
    
    if ([string]::IsNullOrEmpty($OutputPath)) {
        $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
        $siteName = ($Url -split "/")[-1]
        $OutputPath = Join-Path $ScriptDir "Exports\$siteName-$timestamp"
    }
    
    Write-Host ""
    Write-Info "=== Exporting UCC Site Data ==="
    Write-Info "Source: $Url"
    Write-Info "Output: $OutputPath"
    Write-Host ""
    
    # Create output directory
    if (-not (Test-Path $OutputPath)) {
        New-Item -ItemType Directory -Path $OutputPath -Force | Out-Null
    }
    
    $exportSummary = @{
        SourceUrl = $Url
        ExportDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
        Lists = @()
    }
    
    foreach ($listName in $uccLists) {
        try {
            $list = Get-PnPList -Identity $listName -ErrorAction SilentlyContinue
            if ($list -and $list.ItemCount -gt 0) {
                Write-Info "Exporting '$listName' ($($list.ItemCount) items)..."
                
                $items = Get-PnPListItem -List $listName -PageSize 1000
                $exportData = @()
                
                foreach ($item in $items) {
                    $exportData += $item.FieldValues
                }
                
                $exportFile = Join-Path $OutputPath "$listName.json"
                $exportData | ConvertTo-Json -Depth 10 | Out-File $exportFile -Encoding UTF8
                
                $exportSummary.Lists += @{
                    Name = $listName
                    ItemCount = $list.ItemCount
                    File = "$listName.json"
                }
                
                Write-Success "  Exported $($list.ItemCount) items"
            }
        } catch {
            Write-Warn "  Could not export '$listName': $($_.Exception.Message)"
        }
    }
    
    # Export summary
    $summaryFile = Join-Path $OutputPath "_export_summary.json"
    $exportSummary | ConvertTo-Json -Depth 5 | Out-File $summaryFile -Encoding UTF8
    
    Write-Host ""
    Write-Success "=== Export Complete ==="
    Write-Info "Exported $($exportSummary.Lists.Count) lists"
    Write-Info "Output: $OutputPath"
    
    return $OutputPath
}

function Invoke-FullMigration {
    param(
        [string]$SourceUrl,
        [string]$TargetUrl
    )
    
    if ([string]::IsNullOrEmpty($TargetUrl)) {
        Write-Err "TargetUrl is required for full migration"
        return
    }
    
    Write-Host ""
    Write-Info "=== Full Migration ==="
    Write-Info "Source: $SourceUrl"
    Write-Info "Target: $TargetUrl"
    Write-Host ""
    
    # Step 1: Export data
    Write-Info "Step 1: Exporting source data..."
    $exportPath = Export-UccSiteData -Url $SourceUrl
    
    # Step 2: Create new site using UCC.Site.Creator
    Write-Host ""
    Write-Info "Step 2: Creating new site..."
    
    $siteCreatorScript = Join-Path $ScriptDir "UCC.Site.Creator.ps1"
    if (Test-Path $siteCreatorScript) {
        $siteName = ($TargetUrl -split "/")[-1]
        $siteTitle = "UCC - $siteName"
        
        $createArgs = @{
            paramUccName = $siteName
            paramUccTitle = $siteTitle
            paramSiteCollectionUrl = $TargetUrl
            ignoreRestartPowerShell = $true
        }
        if ($Interactive -and $ClientId) {
            $createArgs.Interactive = $true
            $createArgs.paramInteractiveClientId = $ClientId
        }
        
        try {
            & $siteCreatorScript @createArgs
            Write-Success "New site created"
        } catch {
            Write-Err "Failed to create new site: $($_.Exception.Message)"
            return
        }
    } else {
        Write-Err "UCC.Site.Creator.ps1 not found"
        return
    }
    