
param(
    [string]$Server,
    [string]$Destination,
    [string]$Token,
    [string]$ADM_USER,
    [string]$ADM_PASSWORD,
    [string]$AppDir
)

# $credFile = Join-Path $AppDir ".scriptCreds"
# $credData = @{}

# Get-Content $credFile | ForEach-Object {
#     if ($_ -match "=") {
#         $key, $value = $_ -split "=", 2
#         $credData[$key.Trim()] = $value.Trim()
#     }
# }
$username = $ADM_USER
$password = $ADM_PASSWORD

$securePass = ConvertTo-SecureString $password -AsPlainText -Force
$credentials = New-Object System.Management.Automation.PSCredential($username, $securePass)



function Update-Server {
    param (
        [string]$Destination,
        [string]$Server,
        [string]$Token
    )
    
    $buildFile = Join-Path $AppDir "package.json"
    $BuildNumber = 1
    $BuildFolder = Join-Path $AppDir "builds"

    $packageJson = Get-Content $buildFile -Raw | ConvertFrom-Json
        
        # Extract the .build property and cast it safely to an integer
        $num = "$($packageJson.version).$(([int]$packageJson.build) -1)" 
    # if (Test-Path $BuildFile) {
    #     # Parse the entire JSON file into a PowerShell object
    #     $packageJson = Get-Content $buildFile -Raw | ConvertFrom-Json
        
    #     # Extract the .build property and cast it safely to an integer
    #     $num = "($packageJson.version).($packageJson.build)" 

    #     if ($null -ne $num) {
    #         $BuildNumber = $num + 1
    #     }
    #     else {
    #         $BuildNumber = 1
    #     }
    # }

    # Get The current Build we have zipped up
    $BuildNumber = $num


    # copy the latest build over
    Write-Host "Forcing the removal of the mapped drive."
    Get-PSDrive -Name "z" -ErrorAction SilentlyContinue | Remove-PSDrive -Force

    try {

        New-PSDrive -Name "z" -PSProvider FileSystem -Root "\\$Server\$Destination" -Credential $credentials 

        # Create the update folder if it doesn't exist
        if (-not (Test-Path -Path "\\$Server\$Destination")) {
            New-Item -ItemType Directory -Path "\\$Server\$Destination" -Force
        }

        # Copying files to the server
        Write-Host "Copying files to $($Server)"
        $zipFile = Join-Path $BuildFolder "LSTV3-$BuildNumber.zip"
        Copy-Item -Path $zipFile -Destination "z:\" -Force
        Write-Host "Files copied to $($Server)"
    }
    catch {
        Write-Host "Error: $_"
    }
    finally {
        # Remove the mapped drive after copying
        if (Get-PSDrive -Name "z" -ErrorAction SilentlyContinue) {
            Write-Host "Removing mapped drive..."
            Remove-PSDrive -Name "z"
        }
    }

    Write-Host "Updating the app to LSTV3-$BuildNumber.zip"
    # do the stop services, unzip, and restart service and pool
    $AppUpdate = {
        param ($Server, $Token, $Destination, $BuildFile)

        function Fix-Env {

                param(
        [Parameter(Mandatory = $true)]
        [string]$Path
    )

    $envFile = Join-Path $Path ".env"
       
       Write-Host "Checking env file: $envFile"

            if (-not (Test-Path $envFile)) {
                Write-Host ".env not found, creating..."
                New-Item -ItemType File -Path $envFile | Out-Null
            }

            $envContent = Get-Content $envFile -Raw

            if ([string]::IsNullOrWhiteSpace($envContent)) {
                $envContent = ""
            }

            $envVarsToAdd = @{
                "PROVIDER"      = "voidauth"
                "CLIENT_ID"     = "crIVcUilFWIS6ME3"
                "CLIENT_SECRET" = "zsJeyjMN2yDDqfyzSsh96OtlA2714F5d"
                "CLIENT_SCOPES" = "openid profile email groups"
                "DISCOVERY_URL" = "https://auth.tuffraid.net/oidc/.well-known/openid-configuration"
                "UMAMI_HOST" = "https://stats.tuffraid.net"
                "UMAMI_WEBSITE_ID" = "49bc2489-3930-4358-a13d-1cc609336572"
            }

            $linesToAppend = @()

            foreach ($key in $envVarsToAdd.Keys) {
                $escapedKey = [regex]::Escape($key)

                if ($envContent -notmatch "(?m)^$escapedKey=") {
                    $linesToAppend += "$key=$($envVarsToAdd[$key])"
                    Write-Host "Adding missing env: $key"
                }
                else {
                    Write-Host "Env exists, skipping add: $key"
                }
            }

            ###### to replace the values of mistakens or something fun where we need to fix across all 17 servers put it here.
            $envVarsToReplace = @{
                # "PORT" = "3000"
                #"URL" = "https://$($Token)prod.alpla.net/lst"
            }

            foreach ($key in $envVarsToReplace.Keys) {
                $value = $envVarsToReplace[$key]
                $escapedKey = [regex]::Escape($key)

                if ($envContent -match "(?m)^$escapedKey=") {
                    Write-Host "Replacing env: $key -> $value"
                    $envContent = $envContent -replace "(?m)^$escapedKey=.*", "$key=$value"
                }
                else {
                    Write-Host "Env not found for replace, skipping: $key"
                }
            }

            if ($linesToAppend.Count -gt 0) {
                if ($envContent.Length -gt 0 -and -not $envContent.EndsWith("`n")) {
                    $envContent += "`r`n"
                }

                $envContent += "`r`n# ---- VoidAuth Config ----`r`n"
                $envContent += ($linesToAppend -join "`r`n")
                Write-Host "Appending new env vars."
            }

            Set-Content -Path $envFile -Value $envContent
            Write-Host "Env update completed."
        }
        
        #convert everything to the server fun
        $LocalPath = $Destination -replace '\$', ':'
        $BuildFileLoc = "$LocalPath\$BuildFile"

        Write-Host "Updating the app to $($BuildFile)"

        Write-Host "Stopping the services to do the updates, pkgs and db changes."
        $app_name = "LSTV3_app$(if ($Token -eq "usiow2") { "_2" })"

        # TODO: add in the iis reset later

        Write-Host "Stopping $($app_name)"
        Stop-Service -DisplayName $app_name -Force
        Start-Sleep -Seconds 1

        Write-Host "Removing old server"

        # Remove old dist folder before extracting
        $DistPath = Join-Path $LocalPath "dist"

        if (Test-Path $DistPath) {
            Write-Host "Removing old dist folder..."

            try {
                Remove-Item $DistPath -Recurse -Force
            }
            catch {
                Write-Host "Failed to remove dist folder: $_"
                exit 1
            }
        }

        Write-Host "Unzipping the folder..."

        try {
            # Expand the archive
            Expand-Archive -Path $BuildFileLoc -DestinationPath $LocalPath -Force
        }
        catch {
            Write-Host "Error: $_"
            exit 1  # Exit with a non-zero code if there's an error
        }

        # Delete the zip file after extraction
        Write-Host "Deleting the zip file..."
        Remove-Item -Path $BuildFileLoc -Force
        Start-Sleep -Seconds 1

        try {
        # do the install/update
            Push-Location $LocalPath
            Write-Host "Running install/update in: $LocalPath"
            npm install --omit=dev
            Start-Sleep -Seconds 3
            Write-Host "Install/update completed." 

            # update the env to include the new and missing things silly people and wanting things fixed :(
            Fix-Env -Path $LocalPath  

            # do the migrations
            # Push-Location $LocalPath
            Write-Host "Running migrations"
            npm run dev:db:migrate
            Start-Sleep -Seconds 3
            Write-Host "Migrations Completed."   
        }
        catch {
            Write-Host "Migration: $_"
        }
        finally {
            Pop-Location
        }


        Write-Host "Starting $($app_name)"
        Start-Service -DisplayName $app_name -ErrorAction Stop
        Start-Sleep -Seconds 1
        #Write-Host "Update completed on $($Server)-$($Token)"

    }

    Invoke-Command -ComputerName $Server -ScriptBlock $AppUpdate -ArgumentList $Server, $Token, $Destination, "LSTV3-$BuildNumber.zip" -Credential $credentials
}

Update-Server -Server $Server -Destination $Destination -Token $Token