<#
.SYNOPSIS
    ROA2WEB - Auto-Deploy Setup Wizard (Server-Side)

.DESCRIPTION
    Interactive wizard to configure automatic deployment monitoring on Windows Server.
    Creates scheduled task that runs Check-And-Deploy.ps1 at specified intervals.

.PARAMETER MonitorPath
    Path to monitor for deployment packages (default: C:\Temp)

.PARAMETER ScriptsPath
    Path where Check-And-Deploy.ps1 is located (default: C:\Temp\ROA2WEB-Scripts)

.PARAMETER CheckIntervalMinutes
    How often to check for new packages in minutes (default: 5)

.PARAMETER AutoDeploy
    Automatically deploy new packages when found (default: true)

.PARAMETER CreateScheduledTask
    Create Windows Scheduled Task for automation (default: true)

.PARAMETER NonInteractive
    Run in non-interactive mode with provided parameters

.EXAMPLE
    .\Setup-AutoDeploy.ps1
    Launch interactive setup wizard

.EXAMPLE
    .\Setup-AutoDeploy.ps1 -NonInteractive -MonitorPath "C:\Temp" -CheckIntervalMinutes 5
    Non-interactive setup with defaults

.NOTES
    Author: ROA2WEB Team
    Version: 1.0 (Auto-Deploy Setup)
    Requires: Administrator privileges, PowerShell 5.1+
#>

[CmdletBinding()]
param(
    [string]$MonitorPath = "C:\Temp",
    [string]$ScriptsPath = "C:\Temp\ROA2WEB-Scripts",
    [int]$CheckIntervalMinutes = 5,
    [bool]$AutoDeploy = $true,
    [bool]$CreateScheduledTask = $true,
    [switch]$NonInteractive
)

$ErrorActionPreference = "Stop"

# =============================================================================
# HELPER FUNCTIONS
# =============================================================================

function Write-Step {
    param([string]$Message)
    Write-Host "`n[*] $Message" -ForegroundColor Cyan
}

function Write-Success {
    param([string]$Message)
    Write-Host "    [OK] $Message" -ForegroundColor Green
}

function Write-Error {
    param([string]$Message)
    Write-Host "    [ERROR] $Message" -ForegroundColor Red
}

function Write-Warning {
    param([string]$Message)
    Write-Host "    [WARN] $Message" -ForegroundColor Yellow
}

function Write-Info {
    param([string]$Message)
    Write-Host "    [*] $Message" -ForegroundColor Yellow
}

# =============================================================================
# WIZARD FUNCTIONS
# =============================================================================

function Show-WizardWelcome {
    Clear-Host
    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  ROA2WEB - Auto-Deploy Setup Wizard" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  This wizard will configure automatic deployment monitoring." -ForegroundColor Yellow
    Write-Host ""
    Write-Host "  What it does:" -ForegroundColor White
    Write-Host "  - Creates directory structure for auto-deployment" -ForegroundColor Gray
    Write-Host "  - Copies Check-And-Deploy.ps1 to scripts folder" -ForegroundColor Gray
    Write-Host "  - Creates Windows Scheduled Task for monitoring" -ForegroundColor Gray
    Write-Host "  - Configures auto-deploy settings" -ForegroundColor Gray
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "Press any key to continue or Ctrl+C to cancel..." -ForegroundColor Yellow
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

function Get-WizardInput {
    param(
        [string]$Prompt,
        [string]$Default,
        [switch]$IsNumber,
        [switch]$IsYesNo
    )

    do {
        Write-Host "`n$Prompt" -ForegroundColor Yellow
        if ($Default) {
            Write-Host "  Default: $Default" -ForegroundColor Gray
        }
        Write-Host "  > " -NoNewline -ForegroundColor Cyan
        $input = Read-Host

        # Use default if empty
        if ([string]::IsNullOrWhiteSpace($input) -and $Default) {
            return $Default
        }

        # Validate number
        if ($IsNumber) {
            $num = 0
            if ([int]::TryParse($input, [ref]$num) -and $num -gt 0) {
                return $num
            } else {
                Write-Host "  Invalid number. Please enter a positive integer." -ForegroundColor Red
                continue
            }
        }

        # Validate Yes/No
        if ($IsYesNo) {
            $normalized = $input.ToUpper()
            if ($normalized -eq "Y" -or $normalized -eq "YES") {
                return $true
            } elseif ($normalized -eq "N" -or $normalized -eq "NO") {
                return $false
            } else {
                Write-Host "  Invalid input. Please enter Y or N." -ForegroundColor Red
                continue
            }
        }

        return $input
    } while ($true)
}

# =============================================================================
# SETUP FUNCTIONS
# =============================================================================

function Test-Prerequisites {
    Write-Step "Checking prerequisites..."

    # Check Administrator
    $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($currentUser)
    $isAdmin = $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

    if (-not $isAdmin) {
        throw "This script requires Administrator privileges"
    }
    Write-Success "Running as Administrator"

    # Check PowerShell version
    if ($PSVersionTable.PSVersion.Major -lt 5) {
        throw "PowerShell 5.1 or higher is required"
    }
    Write-Success "PowerShell version: $($PSVersionTable.PSVersion)"

    # Check if Check-And-Deploy.ps1 exists
    $checkDeployScript = Join-Path $PSScriptRoot "Check-And-Deploy.ps1"
    if (-not (Test-Path $checkDeployScript)) {
        throw "Check-And-Deploy.ps1 not found in: $PSScriptRoot"
    }
    Write-Success "Check-And-Deploy.ps1 found"

    return $true
}

function New-DirectoryStructure {
    param(
        [string]$MonitorPath,
        [string]$ScriptsPath
    )

    Write-Step "Creating directory structure..."

    # Create monitor path
    if (-not (Test-Path $MonitorPath)) {
        New-Item -ItemType Directory -Path $MonitorPath -Force | Out-Null
        Write-Success "Created: $MonitorPath"
    } else {
        Write-Success "Already exists: $MonitorPath"
    }

    # Create scripts path
    if (-not (Test-Path $ScriptsPath)) {
        New-Item -ItemType Directory -Path $ScriptsPath -Force | Out-Null
        Write-Success "Created: $ScriptsPath"
    } else {
        Write-Success "Already exists: $ScriptsPath"
    }

    # Create logs directory
    $logsPath = Join-Path $ScriptsPath "Logs"
    if (-not (Test-Path $logsPath)) {
        New-Item -ItemType Directory -Path $logsPath -Force | Out-Null
        Write-Success "Created: $logsPath"
    } else {
        Write-Success "Already exists: $logsPath"
    }

    return $true
}

function Copy-MonitorScript {
    param(
        [string]$SourcePath,
        [string]$DestPath
    )

    Write-Step "Copying Check-And-Deploy.ps1 to scripts folder..."

    $sourceScript = Join-Path $SourcePath "Check-And-Deploy.ps1"
    $destScript = Join-Path $DestPath "Check-And-Deploy.ps1"

    # Check if source and destination are the same file
    $sourceFull = (Resolve-Path $sourceScript -ErrorAction SilentlyContinue).Path
    $destFull = (Resolve-Path $destScript -ErrorAction SilentlyContinue).Path

    if ($sourceFull -and $destFull -and ($sourceFull -eq $destFull)) {
        Write-Success "Script already in target location: $destScript"
        return $destScript
    }

    try {
        Copy-Item -Path $sourceScript -Destination $destScript -Force
        Write-Success "Script copied to: $destScript"
        return $destScript
    } catch {
        Write-Error "Failed to copy script: $_"
        return $null
    }
}

function New-ScheduledTaskForAutoDeployNew {
    param(
        [string]$ScriptPath,
        [int]$IntervalMinutes,
        [string]$MonitorPath
    )

    Write-Step "Creating Windows Scheduled Task..."

    $taskName = "ROA2WEB-AutoDeploy"

    # Remove existing task if present
    $existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
    if ($existingTask) {
        Write-Info "Removing existing task..."
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false
    }

    try {
        # Create action
        $action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
            -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`" -WatchPath `"$MonitorPath`""

        # Create trigger (repeat indefinitely every X minutes)
        # Note: When RepetitionDuration is not specified, the task repeats indefinitely
        $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) `
            -RepetitionInterval (New-TimeSpan -Minutes $IntervalMinutes)

        # Create settings
        $settings = New-ScheduledTaskSettingsSet `
            -AllowStartIfOnBatteries `
            -DontStopIfGoingOnBatteries `
            -StartWhenAvailable `
            -RunOnlyIfNetworkAvailable:$false `
            -DontStopOnIdleEnd `
            -MultipleInstances IgnoreNew

        # Register task (run as SYSTEM)
        Register-ScheduledTask -TaskName $taskName `
            -Action $action `
            -Trigger $trigger `
            -Settings $settings `
            -User "SYSTEM" `
            -RunLevel Highest `
            -Description "Monitors $MonitorPath for new deployment packages and auto-deploys them" | Out-Null

        Write-Success "Scheduled task created: $taskName"
        Write-Success "Interval: Every $IntervalMinutes minutes"
        Write-Success "User: SYSTEM"
        Write-Success "Status: Enabled"

        return $true
    } catch {
        Write-Error "Failed to create scheduled task: $_"
        return $false
    }
}

function Show-SetupSummary {
    param(
        [hashtable]$Config
    )

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Setup Summary" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  Monitor Path:       $($Config.MonitorPath)" -ForegroundColor Gray
    Write-Host "  Scripts Path:       $($Config.ScriptsPath)" -ForegroundColor Gray
    Write-Host "  Check Interval:     $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
    Write-Host "  Auto-Deploy:        $($Config.AutoDeploy)" -ForegroundColor Gray
    Write-Host "  Scheduled Task:     $($Config.CreateScheduledTask)" -ForegroundColor Gray
    Write-Host ""
    Write-Host ("=" * 70) -ForegroundColor Cyan
    Write-Host ""
    Write-Host "Proceed with setup? [Y/N]: " -ForegroundColor Yellow -NoNewline
    $confirm = Read-Host

    return ($confirm.ToUpper() -eq "Y" -or $confirm.ToUpper() -eq "YES")
}

# =============================================================================
# MAIN SETUP FLOW
# =============================================================================

function Invoke-Setup {
    param([hashtable]$Config)

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Starting Setup" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan

    try {
        # Test prerequisites
        Test-Prerequisites | Out-Null

        # Create directory structure
        New-DirectoryStructure -MonitorPath $Config.MonitorPath -ScriptsPath $Config.ScriptsPath | Out-Null

        # Copy monitor script
        $scriptPath = Copy-MonitorScript -SourcePath $PSScriptRoot -DestPath $Config.ScriptsPath

        if (-not $scriptPath) {
            throw "Failed to copy monitor script"
        }

        # Create scheduled task if requested
        if ($Config.CreateScheduledTask) {
            $taskSuccess = New-ScheduledTaskForAutoDeployNew `
                -ScriptPath $scriptPath `
                -IntervalMinutes $Config.CheckIntervalMinutes `
                -MonitorPath $Config.MonitorPath

            if (-not $taskSuccess) {
                throw "Failed to create scheduled task"
            }
        }

        Write-Host "`n" + ("=" * 70) -ForegroundColor Green
        Write-Host "  SETUP COMPLETED SUCCESSFULLY" -ForegroundColor Green
        Write-Host ("=" * 70) -ForegroundColor Green
        Write-Host ""
        Write-Host "  Next Steps:" -ForegroundColor Yellow
        Write-Host "  1. Deploy packages will be placed in: $($Config.MonitorPath)" -ForegroundColor Gray
        Write-Host "  2. Server will check for updates every $($Config.CheckIntervalMinutes) minutes" -ForegroundColor Gray
        Write-Host "  3. New packages will be deployed automatically" -ForegroundColor Gray
        Write-Host ""
        Write-Host "  Manual Testing:" -ForegroundColor Yellow
        Write-Host "  - Test: cd $($Config.ScriptsPath) && .\\Check-And-Deploy.ps1 -Interactive" -ForegroundColor Gray
        Write-Host "  - View Task: Get-ScheduledTask -TaskName 'ROA2WEB-AutoDeploy'" -ForegroundColor Gray
        Write-Host ""
        Write-Host ("=" * 70) -ForegroundColor Green

        return $true
    } catch {
        Write-Host "`n" + ("=" * 70) -ForegroundColor Red
        Write-Host "  SETUP FAILED" -ForegroundColor Red
        Write-Host ("=" * 70) -ForegroundColor Red
        Write-Host ""
        Write-Error $_
        Write-Host ""
        Write-Host ("=" * 70) -ForegroundColor Red

        return $false
    }
}

# =============================================================================
# MAIN EXECUTION FLOW
# =============================================================================

function Main {
    # Non-interactive mode
    if ($NonInteractive) {
        $config = @{
            MonitorPath = $MonitorPath
            ScriptsPath = $ScriptsPath
            CheckIntervalMinutes = $CheckIntervalMinutes
            AutoDeploy = $AutoDeploy
            CreateScheduledTask = $CreateScheduledTask
        }

        Invoke-Setup -Config $config | Out-Null
        return
    }

    # Interactive mode - Wizard
    Show-WizardWelcome

    Write-Host "`n" + ("=" * 70) -ForegroundColor Cyan
    Write-Host "  Configuration Wizard" -ForegroundColor Cyan
    Write-Host ("=" * 70) -ForegroundColor Cyan

    # Step 1: Monitor Path
    $monitorPath = Get-WizardInput -Prompt "[1/5] Deploy Folder Path`n  Path to monitor for new deployment packages:" -Default $MonitorPath

    # Step 2: Scripts Path
    $scriptsPath = Get-WizardInput -Prompt "[2/5] Scripts Folder Path`n  Path to store monitoring scripts:" -Default $ScriptsPath

    # Step 3: Check Interval
    $checkInterval = Get-WizardInput -Prompt "[3/5] Check Interval`n  How often to check for updates (minutes):" -Default $CheckIntervalMinutes -IsNumber

    # Step 4: Auto-Deploy
    Write-Host "`n[4/5] Auto-Deploy Enabled" -ForegroundColor Yellow
    Write-Host "  Deploy automatically when new package found?" -ForegroundColor Yellow
    Write-Host "  [Y] Yes (recommended)  [N] No (manual trigger only)" -ForegroundColor Gray
    $autoDeploy = Get-WizardInput -Prompt "  Your choice:" -Default "Y" -IsYesNo

    # Step 5: Scheduled Task
    Write-Host "`n[5/5] Create Scheduled Task" -ForegroundColor Yellow
    Write-Host "  Create Windows Scheduled Task for automatic monitoring?" -ForegroundColor Yellow
    Write-Host "  [Y] Yes  [N] No" -ForegroundColor Gray
    $createTask = Get-WizardInput -Prompt "  Your choice:" -Default "Y" -IsYesNo

    # Configuration object
    $config = @{
        MonitorPath = $monitorPath
        ScriptsPath = $scriptsPath
        CheckIntervalMinutes = [int]$checkInterval
        AutoDeploy = $autoDeploy
        CreateScheduledTask = $createTask
    }

    # Show summary and confirm
    $confirmed = Show-SetupSummary -Config $config

    if ($confirmed) {
        Invoke-Setup -Config $config
    } else {
        Write-Host "`nSetup cancelled by user" -ForegroundColor Yellow
        exit 0
    }

    Write-Host "`nPress any key to exit..." -ForegroundColor Gray
    $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
}

# Run main
Main
