$ErrorActionPreference = "Stop"


# Script version (should match package version)
$ScriptVersion = "8.4.1.8"
# Resolve RootPath - go up two levels from Scripts folder to package root
# This script is at: <RootPath>/Anywhere365/Scripts/WSP.UCC-1.SiteCollection.ps1
$RootPath = Split-Path (Split-Path $PSScriptRoot -Parent) -Parent

# Validate RootPath
if ([string]::IsNullOrEmpty($RootPath) -or !(Test-Path $RootPath))
{
    Write-Host "Error: Could not determine RootPath from PSScriptRoot: $PSScriptRoot" -ForegroundColor Red
    throw "Invalid RootPath: $RootPath"
}


# Version banner
Write-Host "" 
Write-Host "============================================================" -ForegroundColor Cyan
Write-Host "  AnywhereNow UCC Site Creator v$ScriptVersion" -ForegroundColor Cyan
Write-Host "============================================================" -ForegroundColor Cyan
# Debug output
Write-Host "RootPath resolved to: $RootPath" -ForegroundColor Gray

. $RootPath\AnywhereNow\Scripts\Shared.ps1
. $RootPath\AnywhereNow\Scripts\SharedPnpFunctions.ps1
. $RootPath\AnywhereNow\Scripts\WSP.UCC-0.Update.ps1

function ConfigureSiteCollection
{
    try 
	{
        # NOTE: Classic publishing features (PublishingSite, PublishingWeb) are deprecated per MC1117115
        # and are not available on Communication Sites. These have been removed.
        # Modern Communication Sites use different mechanisms for content publishing.

        # Check if we should skip Custom Script operations
        $skipCustomScript = $global:SkipCustomScriptOperations -eq $true

        # Uploading assets (requires Custom Script for checkout/publish)
		if ($updateLinks -eq $false)
		{
            if ($skipCustomScript)
            {
                Warn "Skipping asset upload (Custom Script disabled). Use SPFx Portal Web Part instead."
            }
            else
            {
			    UploadAssets
            }
		}
		else 
		{
			Info "Updating links only"
		}

		if ($SPversion -eq "online")
		{
			Info "Disabling Modern UI feature"
			Enable-PnPFeature -Identity E3540C7D-6BEA-403C-A224-1A12EAFEE4C4 -Scope Site -ErrorAction SilentlyContinue
        
			Info "Enabling SitePages feature"
			Enable-PnPFeature -Identity b6917cb1-93a0-4b97-a84d-7cf49975d4ec -ErrorAction SilentlyContinue
		}

        $uri = [Uri]$scurl
        $siteCollectionAbsolutePath = $uri.AbsolutePath
		if ($siteCollectionAbsolutePath -eq "/") 
		{
			$siteCollectionAbsolutePath = "";
		}

        # These operations require Custom Script to be enabled
        if ($skipCustomScript)
        {
            Warn "Skipping logo, JavaScriptLink, and CSS settings (Custom Script disabled)"
        }
        else
        {
            Info "Setting logo"
		    SetSiteLogoUrl "$siteCollectionAbsolutePath/Style%20Library/Anywhere365/Images/Logo2x.png"

            Info "Setting JavaScriptLink"
            AddPnPJavaScriptLink "AnywhereNow" "$siteCollectionAbsolutePath/Style%20Library/Anywhere365/A365.js"

            Info "Setting alternate CSS"
		    SetAlternateCssUrl "$siteCollectionAbsolutePath/Style%20Library/Anywhere365/A365.css"
        }
    }
    catch 
	{
        Error "$($_.Exception.Message)"
    }
}

function UccCreatorList 
{
    try 
	{
		# Fields
        Info "Adding site columns"
		AddPnPFieldFromXml '<Field ID="{4a21d905-50c2-4a82-8948-96670cf56726}" Type="Text" Name="A365_SiteTitle" DisplayName="UCC Display Name" Required="TRUE" Description="Display name for your contact center. For example: UCC Reception" Group="Anywhere365 Provisioning Site Columns"></Field>' $null "A365_SiteTitle"
		AddPnPFieldFromXml '<Field ID="{7d6e9eb3-6120-4f7c-b462-d8b068773769}" Type="URL" Name="A365_SiteURL" DisplayName="Site URL" Required="FALSE" Format="Hyperlink" ShowInNewForm="FALSE" ShowInEditForm="FALSE" Group="Anywhere365 Provisioning Site Columns" />' $null "A365_SiteURL"
		AddPnPFieldFromXml '<Field ID="{636cbbea-43c2-4daa-b43b-537abfb8dd91}" Type="Text" Name="A365_ParentSite" DisplayName="Parent Site" Required="FALSE" Sortable="TRUE" Description="URL Parent Site (subsite). Leave it blank if the parent site is the site collection. Example: Europe" Group="Anywhere365 Provisioning Site Columns" />' $null "A365_ParentSite"
		AddPnPFieldFromXml '<Field ID="{4455e24d-71d3-4655-acfb-1cba5c5176a1}" Type="Choice" Name="A365_Language" DisplayName="Language" Required="TRUE" Format="Dropdown" Group="Anywhere365 Provisioning Site Columns">
		<Default>English</Default>
		<CHOICES>
				<CHOICE>Danish</CHOICE>
				<CHOICE>Dutch</CHOICE>
				<CHOICE>English</CHOICE>
				<CHOICE>French</CHOICE>
				<CHOICE>German</CHOICE>
				<CHOICE>Italian</CHOICE>
				<CHOICE>Norwegian</CHOICE>
				<CHOICE>Portuguese</CHOICE>
				<CHOICE>Spanish</CHOICE>
				<CHOICE>Swedish</CHOICE>
		</CHOICES>
		</Field>' $null "A365_Language"
		AddPnPFieldFromXml '<Field ID="{cebdc052-5076-4180-9783-de767ce071b1}" Type="Choice" Name="A365_TimeZone" DisplayName="Time Zone" Required="FALSE" Format="Dropdown" Group="Anywhere365 Provisioning Site Columns">
		<CHOICES>
			<CHOICE>(UTC-12:00) International Date Line West</CHOICE>
			<CHOICE>(UTC-11:00) Coordinated Universal Time-11</CHOICE>
			<CHOICE>(UTC-10:00) Hawaii</CHOICE>
			<CHOICE>(UTC-09:00) Alaska</CHOICE>
			<CHOICE>(UTC-08:00) Baja California</CHOICE>
			<CHOICE>(UTC-08:00) Pacific Time (US and Canada)</CHOICE>
			<CHOICE>(UTC-07:00) Arizona</CHOICE>
			<CHOICE>(UTC-07:00) Chihuahua, La Paz, Mazatlan</CHOICE>
			<CHOICE>(UTC-07:00) Mountain Time (US and Canada)</CHOICE>
			<CHOICE>(UTC-06:00) Central America</CHOICE>
			<CHOICE>(UTC-06:00) Central Time (US and Canada)</CHOICE>
			<CHOICE>(UTC-06:00) Guadalajara, Mexico City, Monterrey</CHOICE>
			<CHOICE>(UTC-06:00) Saskatchewan</CHOICE>
			<CHOICE>(UTC-05:00) Bogota, Lima, Quito</CHOICE>
			<CHOICE>(UTC-05:00) Eastern Time (US and Canada)</CHOICE>
			<CHOICE>(UTC-05:00) Indiana (East)</CHOICE>
			<CHOICE>(UTC-04:30) Caracas</CHOICE>
			<CHOICE>(UTC-04:00) Asuncion</CHOICE>
			<CHOICE>(UTC-04:00) Atlantic Time (Canada)</CHOICE>
			<CHOICE>(UTC-04:00) Cuiaba</CHOICE>
			<CHOICE>(UTC-04:00) Georgetown, La Paz, Manaus, San Juan</CHOICE>
			<CHOICE>(UTC-03:30) Newfoundland</CHOICE>
			<CHOICE>(UTC-03:00) Brasilia</CHOICE>
			<CHOICE>(UTC-03:00) Buenos Aires</CHOICE>
			<CHOICE>(UTC-03:00) Cayenne, Fortaleza</CHOICE>
			<CHOICE>(UTC-03:00) Greenland</CHOICE>
			<CHOICE>(UTC-03:00) Montevideo</CHOICE>
			<CHOICE>(UTC-03:00) Salvador</CHOICE>
			<CHOICE>(UTC-03:00) Santiago</CHOICE>
			<CHOICE>(UTC-02:00) Coordinated Universal Time-02</CHOICE>
			<CHOICE>(UTC-02:00) Mid-Atlantic</CHOICE>
			<CHOICE>(UTC-01:00) Azores</CHOICE>
			<CHOICE>(UTC-01:00) Cabo Verde</CHOICE>
			<CHOICE>(UTC) Casablanca</CHOICE>
			<CHOICE>(UTC) Coordinated Universal Time</CHOICE>
			<CHOICE>(UTC) Dublin, Edinburgh, Lisbon, London</CHOICE>
			<CHOICE>(UTC) Monrovia, Reykjavik</CHOICE>
			<CHOICE>(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna</CHOICE>
			<CHOICE>(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague</CHOICE>
			<CHOICE>(UTC+01:00) Brussels, Copenhagen, Madrid, Paris</CHOICE>
			<CHOICE>(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb</CHOICE>
			<CHOICE>(UTC+01:00) West Central Africa</CHOICE>
			<CHOICE>(UTC+01:00) Windhoek</CHOICE>
			<CHOICE>(UTC+02:00) Amman</CHOICE>
			<CHOICE>(UTC+02:00) Athens, Bucharest</CHOICE>
			<CHOICE>(UTC+02:00) Beirut</CHOICE>
			<CHOICE>(UTC+02:00) Cairo</CHOICE>
			<CHOICE>(UTC+02:00) Damascus</CHOICE>
			<CHOICE>(UTC+02:00) Harare, Pretoria</CHOICE>
			<CHOICE>(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius</CHOICE>
			<CHOICE>(UTC+02:00) Jerusalem</CHOICE>
			<CHOICE>(UTC+02:00) Minsk (old)</CHOICE>
			<CHOICE>(UTC+02:00) E. Europe</CHOICE>
			<CHOICE>(UTC+02:00) Kaliningrad</CHOICE>
			<CHOICE>(UTC+03:00) Baghdad</CHOICE>
			<CHOICE>(UTC+03:00) Istanbul</CHOICE>
			<CHOICE>(UTC+03:00) Kuwait, Riyadh</CHOICE>
			<CHOICE>(UTC+03:00) Minsk</CHOICE>
			<CHOICE>(UTC+03:00) Moscow, St. Petersburg, Volgograd</CHOICE>
			<CHOICE>(UTC+03:00) Nairobi</CHOICE>
			<CHOICE>(UTC+03:30) Tehran</CHOICE>
			<CHOICE>(UTC+04:00) Abu Dhabi, Muscat</CHOICE>
			<CHOICE>(UTC+04:00) Astrakhan, Ulyanovsk</CHOICE>
			<CHOICE>(UTC+04:00) Baku</CHOICE>
			<CHOICE>(UTC+04:00) Izhevsk, Samara</CHOICE>
			<CHOICE>(UTC+04:00) Port Louis</CHOICE>
			<CHOICE>(UTC+04:00) Tbilisi</CHOICE>
			<CHOICE>(UTC+04:00) Yerevan</CHOICE>
			<CHOICE>(UTC+04:30) Kabul</CHOICE>
			<CHOICE>(UTC+05:00) Ekaterinburg</CHOICE>
			<CHOICE>(UTC+05:00) Islamabad, Karachi</CHOICE>
			<CHOICE>(UTC+05:00) Tashkent</CHOICE>
			<CHOICE>(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi</CHOICE>
			<CHOICE>(UTC+05:30) Sri Jayawardenepura</CHOICE>
			<CHOICE>(UTC+05:45) Kathmandu</CHOICE>
			<CHOICE>(UTC+06:00) Astana</CHOICE>
			<CHOICE>(UTC+06:00) Dhaka</CHOICE>
			<CHOICE>(UTC+06:00) Omsk</CHOICE>
			<CHOICE>(UTC+06:30) Yangon (Rangoon)</CHOICE>
			<CHOICE>(UTC+07:00) Bangkok, Hanoi, Jakarta</CHOICE>
			<CHOICE>(UTC+07:00) Barnaul, Gorno-Altaysk</CHOICE>
			<CHOICE>(UTC+07:00) Krasnoyarsk</CHOICE>
			<CHOICE>(UTC+07:00) Novosibirsk</CHOICE>
			<CHOICE>(UTC+07:00) Tomsk</CHOICE>
			<CHOICE>(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi</CHOICE>
			<CHOICE>(UTC+08:00) Irkutsk</CHOICE>
			<CHOICE>(UTC+08:00) Kuala Lumpur, Singapore</CHOICE>
			<CHOICE>(UTC+08:00) Perth</CHOICE>
			<CHOICE>(UTC+08:00) Taipei</CHOICE>
			<CHOICE>(UTC+08:00) Ulaanbaatar</CHOICE>
			<CHOICE>(UTC+09:00) Osaka, Sapporo, Tokyo</CHOICE>
			<CHOICE>(UTC+09:00) Seoul</CHOICE>
			<CHOICE>(UTC+09:00) Yakutsk</CHOICE>
			<CHOICE>(UTC+09:30) Adelaide</CHOICE>
			<CHOICE>(UTC+09:30) Darwin</CHOICE>
			<CHOICE>(UTC+10:00) Brisbane</CHOICE>
			<CHOICE>(UTC+10:00) Canberra, Melbourne, Sydney</CHOICE>
			<CHOICE>(UTC+10:00) Guam, Port Moresby</CHOICE>
			<CHOICE>(UTC+10:00) Hobart</CHOICE>
			<CHOICE>(UTC+10:00) Magadan</CHOICE>
			<CHOICE>(UTC+10:00) Vladivostok</CHOICE>
			<CHOICE>(UTC+11:00) Chokurdakh</CHOICE>
			<CHOICE>(UTC+11:00) Sakhalin</CHOICE>
			<CHOICE>(UTC+11:00) Solomon Is., New Caledonia</CHOICE>
			<CHOICE>(UTC+12:00) Anadyr, Petropavlovsk-Kamchatsky</CHOICE>
			<CHOICE>(UTC+12:00) Auckland, Wellington</CHOICE>
			<CHOICE>(UTC+12:00) Coordinated Universal Time+12</CHOICE>
			<CHOICE>(UTC+12:00) Fiji</CHOICE>
			<CHOICE>(UTC+12:00) Petropavlovsk-Kamchatsky - Old</CHOICE>
			<CHOICE>(UTC+13:00) Nuku alofa</CHOICE>
			<CHOICE>(UTC+13:00) Samoa</CHOICE>
		</CHOICES>
		</Field>' $null "A365_TimeZone"
		AddPnPFieldFromXml '<Field ID="{c5d84c7b-8fed-4823-9e00-4077770b4f51}" Type="UserMulti" Name="A365_SiteOwners" DisplayName="Site Owners" Required="TRUE" List="UserInfo" ShowField="ImnName" UserSelectionMode="PeopleOnly" UserSelectionScope="0" Mult="TRUE" Description="The Site Owners are appointed by the Business Owner and will have Full Control on the site and are responsible for managing content and permission within a site." ShowInNewForm="TRUE" ShowInEditForm="FALSE" ShowInDisplayForm="TRUE" Group="Anywhere365 Provisioning Site Columns"  />' $null "A365_SiteOwners"
		AddPnPFieldFromXml '<Field ID="{e4cd48a9-2c5c-4f60-86ff-a9bf4fb0d110}" Type="UserMulti" Name="A365_SiteMembers" DisplayName="Site Members" Required="FALSE" List="UserInfo" ShowField="ImnName" UserSelectionMode="PeopleAndGroups" UserSelectionScope="0" Mult="TRUE" Sortable="FALSE" Description="Site Members will be able to Contribute (read, create, edit and delete) content on your site." ShowInNewForm="TRUE" ShowInEditForm="FALSE" ShowInDisplayForm="TRUE" Group="Anywhere365 Provisioning Site Columns" />' $null "A365_SiteMembers"
		AddPnPFieldFromXml '<Field ID="{4330bb13-b27d-4a71-81a5-2b65a7547f56}" Type="UserMulti" Name="A365_SiteVisitors" DisplayName="Site Visitors" Required="FALSE" List="UserInfo" ShowField="ImnName" UserSelectionMode="PeopleAndGroups" UserSelectionScope="0" Mult="TRUE" Sortable="FALSE" Description="Site Visitors will be able to Read content on your site." ShowInNewForm="TRUE" ShowInEditForm="FALSE" ShowInDisplayForm="TRUE" Group="Anywhere365 Provisioning Site Columns" />' $null "A365_SiteVisitors"
		AddPnPFieldFromXml '<Field ID="{465ba4e9-aa5d-480f-b83a-2be27f472bea}" Type="Choice" Name="A365_SiteStatus" DisplayName="Provision Status" Required="FALSE" Format="Dropdown" ShowInNewForm="FALSE" ShowInEditForm="FALSE" Group="Anywhere365 Provisioning Site Columns">
		<Default>Requested</Default>
		<CHOICES>
			<CHOICE>Requested</CHOICE>
			<CHOICE>Provisioned</CHOICE>
		</CHOICES>
		</Field>' $null "A365_SiteStatus"
		AddPnPFieldFromXml '<Field ID="{5f26dc17-6cd3-4c20-9c94-c31e66363bc5}" Type="Text" Name="A365_SipDomain" DisplayName="Sip Domain" Required="FALSE" Sortable="TRUE" Description="For example: anywhere365.io" Group="Anywhere365 Provisioning Site Columns" />' $null "A365_SipDomain"
		AddPnPFieldFromXml '<Field ID="{51ffa650-1cf4-461c-8b0e-7f5b8a0cac8a}" Type="Note" Name="A365_CDRConnectionString" DisplayName="CDR Connection String" Required="FALSE" Sortable="TRUE" Description="example: Data Source=localhost\UCCSQL;Initial Catalog=UCC;Integrated Security=True" Group="Anywhere365 Provisioning Site Columns" NumLines="6" RichText="FALSE" />' $null "A365_CDRConnectionString"
		# CT
		Info "Adding site content types"
        $a365toplevelct = "A365 Top Level Site Element"                                                              
        $a365ct = "A365 Site" 
		AddPnPContentType $a365toplevelct "0x01004814c7b708e94f0fa2975de7688b95f3"
		AddPnPContentType $a365ct "0x010017876000c042448fa491ed94bc6ff26a"
        Info "Adding site columns to the content types"
		AddPnPFieldsToContentType $a365ct @("!A365_SiteTitle", "A365_SiteURL", "!A365_Language", "A365_TimeZone", "A365_SiteStatus", "A365_SipDomain", "A365_CDRConnectionString", "A365_ParentSite")

		# Creator list
		Info "Adding UCC Creator list"
        $listName = "A365_UCC_Creator"
		$listTitle = "AnywhereNow UCC Creator"
		$added = AddPnPList $listTitle $listName -RemoveDefaultView
		if ($added -eq $false)
		{
			Info "List already exists"
			return
		}
	
        Info "Adding content type to UCC Creator list"
		AddPnPContentTypesToList $listTitle @($a365ct)

        Info "Adding view to UCC Creator list"
		# Configure view and Parent Site field visibility based on subsite mode
		if ($useSubSites) {
			# Include Parent Site column in the view when subsite mode is enabled
			AddPnPView $listTitle "AllItems" "AllItems" 30 '<OrderBy><FieldRef Name="ID" Ascending="$false" /></OrderBy>' @("LinkTitle", "A365_SiteTitle", "A365_SiteURL", "A365_ParentSite", "A365_SiteStatus", "Modified") -Default

			# Show Parent Site in display form only (auto-filled during provisioning, not user-editable)
			$parentSiteField = GetPnPField "A365_ParentSite" $listTitle
			$parentSiteField.SetShowInDisplayForm($true)
			$parentSiteField.SetShowInEditForm($false)
			$parentSiteField.SetShowInNewForm($false)
			$parentSiteField.Update()
		} else {
			# Simplified view without ParentSite (original behaviour)
			AddPnPView $listTitle "AllItems" "AllItems" 30 '<OrderBy><FieldRef Name="ID" Ascending="$false" /></OrderBy>' @("LinkTitle", "A365_SiteTitle", "A365_SiteURL", "A365_SiteStatus", "Modified") -Default

			# Hide Parent Site field since subsites are not in use
			$parentSiteField = GetPnPField "A365_ParentSite" $listTitle
			$parentSiteField.SetShowInDisplayForm($false)
			$parentSiteField.SetShowInEditForm($false)
			$parentSiteField.SetShowInNewForm($false)
			$parentSiteField.Update()
		}
        
		# Set unique field
		$titleField = GetPnPField "Title" $listTitle
        $titleField.Title = "UCC Name"
		$titleField.Description = "Only use lower case characters, numbers and hyphens. For example: ucc-reception"
        $titleField.EnforceUniqueValues = $true
        $titleField.Indexed = $true
        $titleField.Update()

        Invoke-PnPQuery
    }
    catch 
	{
        Error "$($_.Exception.Message)"
    }    
}

function AddClientSidePage 
{
    try 
	{
        Info "Adding client side page"
    
		if ($SPversion -eq "online")
		{
			try 
			{
				Get-PnPPage "default" | Out-Null
				Info "Page already exists"
				return
			}
			catch { }

			$page = Add-PnPPage -Name "default" -LayoutType Home -Title "AnywhereNow UCC Creator"
			Add-PnPPageSection -Page $page -SectionTemplate OneColumn | Out-Null
			Set-PnPPage -Identity $page -CommentsEnabled:$false | Out-Null

			$list = Get-PnPList "Lists/A365_UCC_Creator"
			$listId = $list.Id
			Add-PnPPageWebPart -Page $page -DefaultWebPartType "List" -WebPartProperties @{selectedListId = $listId} | Out-Null
			Set-PnPPage -Identity $page -Publish | Out-Null
			SetPnPHomePage "SitePages/default.aspx"
		}
		else
		{
			try 
			{
				Get-PnPClientSidePage "default" | Out-Null
				Info "Page already exists"
				return
			}
			catch { }

			$page = Add-PnPClientSidePage -Name "default" -LayoutType Home
			Add-PnPClientSidePageSection -Page $page -SectionTemplate OneColumn | Out-Null
			Set-PnPClientSidePage -Identity $page -CommentsEnabled:$false | Out-Null

			$list = GetPnPList "Lists/A365_UCC_Creator"
			$listId = $list.Id
			Add-PnPClientSideWebPart -Page $page -DefaultWebPartType "List" -WebPartProperties @{selectedListId = $listId} | Out-Null
			Set-PnPClientSidePage -Identity $page -Publish | Out-Null
			SetPnPHomePage "SitePages/default.aspx"
		}
    }
    catch 
	{
        Error "$($_.Exception.Message)"
    } 
}

function EnsureSite
{
	# Check vars
	$checkVars = CheckEnvironmentalVariables
	if ($checkVars -eq $false) 
	{
		Warn "Required variables not set"
		return
	}

	if ($SPversion -ne "2013" -and $SPversion -ne "2016" -and $SPversion -ne "2019" -and $SPversion -ne "online" -and $SPversion -ne "foundation") 
	{
		Warn "SP version '$SPversion' not supported. Use online, 2013, 2016, 2019 or foundation"
		return
    }

	$connected = Connect -Url $scurl -ShowError
	if (-not $connected) 
	{
		Warn "Cannot connect to sitecollection $scurl"
		return
	}

	Info "Sitecollection creator started"
	Info "Connected to site collection $scurl"
	if ($SPversion -eq "online")
	{
		if (!$(CheckDenyAddCustomisePagesFeature)) 
		{
			Warn "Custom Script is disabled. Classic portal.aspx will not work - use SPFx Portal Web Part instead."
		}
	}

	ConfigureSiteCollection
	if ($updateLinks -eq $false) 
	{
		UccCreatorList
		AssetsVersionList
		if ($SPversion -eq "online")
		{
			AddClientSidePage
		}

		ExecuteNewSiteCollectionUpdate
	}

	Disconnect-PnPOnline
	Info "Done"
}
