function Update-Server {
    param (
        [string]$ADM_USER,
        [string]$ADM_PASS,
        [string]$AppRoot,
        [string]$Destination,
        [string]$Server,
        [string]$Token,
        [string]$ControllerBuild       

    )

    $BuildFile = Join-Path $AppRoot ".controller-build"
    $BuildFolder = Join-Path $AppRoot "controllerBuilds"

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


    # Default to 1
    $BuildNumber = 1


    if (Test-Path $BuildFile) {
        $content = Get-Content $BuildFile | Select-Object -First 1
        $num = $content.Trim() -as [int]  # safe cast

        if ($num) {
            $BuildNumber = $num + 1
        }
        else {
            $BuildNumber = 1
        }
    }

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

    # Convert to string
    if ($ControllerBuild -eq "yes") {
        $BuildNumber = $BuildNumber.ToString()
    }
    else {
        $BuildNumber = ([int]$BuildNumber - 1).ToString()
    }
    

    # 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 "controllers-$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"
        }
    }

    # do the stop services, unzip, and restart service and pool

    $ControllerUpdate = {
        param ($Server, $Token, $Destination, $BuildFile)
    

        write-host "Running the update process now"
        # Change the destination to be local
        $LocalPath = $Destination -replace '\$', ':'
        $BuildFileLoc = "$LocalPath\$BuildFile"

        # where is nssm.exe
        #$nssmPath = Join-Path $LocalPath "nssm.exe"
        #$npmPath = "C:\Program Files\nodejs\npm.cmd"

        Write-Host "Stopping the services to do the updates, pkgs and db changes."

        $Controller = "LST_ctl$(if ($Token -eq "usiow2") { "_2" })"
        $Wrapper = "LogisticsSupportTool$(if ($token -eq "usiow2") { "_2" })"

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

        Write-Host "Stopping $($Wrapper)"
        try {
            Stop-WebAppPool -Name $Wrapper -ErrorAction Stop

            Start-Sleep -Seconds 2
            $state = (Get-WebAppPoolState -Name $Wrapper).Value
            Write-Host "Result: $state"
        }
        catch {
            Write-Error $_.Exception.Message
        }


        Write-Host "Unzipping the folder..."
        #write-host $BuildFileLoc
        #write-host $LocalPath

        # Extract the files to the build path
        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

        Write-Host "Starting $($Controller)"
        Start-Service -DisplayName $Controller
        Start-Sleep -Seconds 1

        Write-Host "Starting $($Wrapper)"
        try {
            Start-WebAppPool -Name $Wrapper
            Start-Sleep -Seconds 2
            $state = (Get-WebAppPoolState -Name $Wrapper).Value
            Write-Host "Result: $state"
        }
        catch {
            Write-Error $_.Exception.Message
            exit 1
        }

        write-host "Controllers updated and restarted :D"

        Start-Sleep 1

        #### This section is ment to be a temporary thing to add the new .env as examples
        write-host "Updating the main env file as we want to add more in and not forget the new stuff as we devlop this more."

        $required = @(
            @{ Key = "BETTER_AUTH_SECRET"; Value = "3d2b7d64ac2f9ebd6854325a84390666f4bbd2c7c3f537bb60fca3740f081e1e"; Comment = "used for better auth secrets" },
            @{ Key = "BETTER_AUTH_URL"; Value = "https://$Server.alpla.net"; Comment = "The better auth url" }
            @{ Key = "NODE_ENV"; Value = "production"; Comment = "Just making sure this is in there." }
        )

        $envFile = "$LocalPath\.env"

        if (-not (Test-Path $envFile)) {
            New-Item -ItemType File -Path $envFile -Force | Out-Null
        }

        $lines = Get-Content $envFile

        foreach ($item in $required) {
            $key = $item.Key
            $value = $item.Value
            $comment = "# $($item.Comment)"

            $exists = $lines | Where-Object { $_ -match "^\s*$key\s*=" }

            if (-not $exists) {
                Write-Output "[$key] missing -> adding to .env"
                Add-Content -Path $envFile -Value "`n$comment"
                Add-Content -Path $envFile -Value "$key=$value"
            }
            else {
                Write-Output "[$key] already exists -> skipping"
            }
        }


        # update the controller .env as well to make sure we have anything enw in here.
        $requiredController = @(
            @{ Key = "DATABASE_HOST"; Value = "localhost"; Comment = "used for better auth secrets" },
            @{ Key = "DATABASE_PORT"; Value = 5432; Comment = "The better auth url" }
            @{ Key = "DATABASE_USER"; Value = "postgres"; Comment = "" }
            @{ Key = "DATABASE_PASSWORD"; Value = "obelix"; Comment = "" }
            @{ Key = "DATABASE_DB"; Value = "lst$(if ($token -eq "usiow2") { "_2" })"; Comment = "" }
        )

        $envFileController = "$LocalPath\controller\.env"
        Write-Host $envFileController

        if (-not (Test-Path $envFileController)) {
            New-Item -ItemType File -Path $envFileController -Force | Out-Null
        }

        $lines = Get-Content $envFileController

        foreach ($item in $requiredController) {
            $key = $item.Key
            $value = $item.Value
            $comment = "# $($item.Comment)"

            $exists = $lines | Where-Object { $_ -match "^\s*$key\s*=" }

            if (-not $exists) {
                Write-Output "[$key] missing -> adding to .env"
                Add-Content -Path $envFileController -Value "`n$comment"
                Add-Content -Path $envFileController -Value "$key=$value"
            }
            else {
                Write-Output "[$key] already exists -> skipping"
            }
        }

    }



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