# =============================================================================
# IntelliCall AI - Setup & Customization Wizard (Windows)
# =============================================================================
# This script guides you through the complete setup of the IntelliCall AI
# platform on Windows.
# Run with: .\setup.ps1 (in PowerShell as Administrator)
# =============================================================================

$ErrorActionPreference = "Stop"

# UI Functions
function Write-Header($text) {
    Write-Host ""
    Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Blue
    Write-Host "  $text" -ForegroundColor Cyan
    Write-Host "═══════════════════════════════════════════════════════════" -ForegroundColor Blue
    Write-Host ""
}

function Write-Success($text) { Write-Host "✅ $text" -ForegroundColor Green }
function Write-Error($text) { Write-Host "❌ $text" -ForegroundColor Red }
function Write-Warning($text) { Write-Host "⚠️  $text" -ForegroundColor Yellow }
function Write-Info($text) { Write-Host "ℹ️  $text" -ForegroundColor Cyan }
function Write-Step($text) { Write-Host "▶ $text" -ForegroundColor Blue }
function Write-Box($title) {
    Write-Host "╭───────────────────────────────────────────────────────────╮" -ForegroundColor Cyan
    $paddedTitle = "│ " + $title
    while ($paddedTitle.Length -lt 59) { $paddedTitle += " " }
    $paddedTitle += "│"
    Write-Host $paddedTitle -ForegroundColor Yellow -NoNewline
    Write-Host ""
    Write-Host "├───────────────────────────────────────────────────────────┤" -ForegroundColor Cyan
}
function Write-BoxFooter {
    Write-Host "╰───────────────────────────────────────────────────────────╯" -ForegroundColor Cyan
}

# Global Paths
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ProjectRoot = Split-Path -Parent $ScriptDir
$BackendDir = Join-Path $ProjectRoot "backend"
$FrontendDir = Join-Path $ProjectRoot "frontend"

# Helper: Backup file
function Backup-File($filePath) {
    if (Test-Path $filePath) {
        $backupPath = "$filePath.bak.$(Get-Date -Format 'yyyyMMdd_HHmmss')"
        Copy-Item $filePath $backupPath
        Write-Info "Backup created: $(Split-Path $backupPath -Leaf)"
    }
}

# Helper: Get input with default
function Get-Input($prompt, $default) {
    $result = Read-Host "  $prompt [$default]"
    if ([string]::IsNullOrWhiteSpace($result)) { return $default }
    return $result
}

# Helper: Update or Add key in .env file
function Update-EnvVar($filePath, $key, $value) {
    if (-not (Test-Path $filePath)) {
        "$key=$value" | Out-File -FilePath $filePath -Encoding utf8
        return
    }

    $lines = Get-Content $filePath
    $found = $false
    $newLines = @()

    foreach ($line in $lines) {
        if ($line -match "^$key=") {
            $newLines += "$key=$value"
            $found = $true
        } else {
            $newLines += $line
        }
    }

    if (-not $found) {
        $newLines += "$key=$value"
    }

    $newLines | Out-File -FilePath $filePath -Encoding utf8
}

# -----------------------------------------------------------------------------
# STEP 1: DEPENDENCY CHECKS
# -----------------------------------------------------------------------------
function Check-Dependencies {
    Write-Header "Checking Dependencies"
    $MissingDeps = $false

    Write-Step "Checking Node.js..."
    try {
        $nodeVersion = node -v
        Write-Success "Node.js $nodeVersion found"
    } catch {
        Write-Error "Node.js not found"
        $MissingDeps = $true
    }

    Write-Step "Checking npm..."
    try {
        $npmVersion = npm -v
        Write-Success "npm v$npmVersion found"
    } catch {
        Write-Error "npm not found"
        $MissingDeps = $true
    }

    if ($MissingDeps) {
        Write-Error "Please install missing dependencies and run setup again."
        exit 1
    }
}

# -----------------------------------------------------------------------------
# STEP 2: MONGODB TEST
# -----------------------------------------------------------------------------
function Test-MongoDB($url) {
    Write-Step "Testing MongoDB connection..."
    if (Get-Command mongosh -ErrorAction SilentlyContinue) {
        $result = mongosh "$url" --eval "db.runCommand({ ping: 1 })" --quiet 2>&1
        if ($LASTEXITCODE -eq 0) { return $true }
    } elseif (Get-Command mongo -ErrorAction SilentlyContinue) {
        $result = mongo "$url" --eval "db.runCommand({ ping: 1 })" --quiet 2>&1
        if ($LASTEXITCODE -eq 0) { return $true }
    } else {
        Write-Warning "No MongoDB client found to test connection. Assuming URL is correct."
        return $true
    }
    return $false
}

# -----------------------------------------------------------------------------
# STEP 2.5: NGROK HELPER
# -----------------------------------------------------------------------------
function Write-NgrokInfo {
    Write-Box "🌍 NGROK GUIDE (LOCAL TESTING)"
    Write-Host "│ 1. Download: https://ngrok.com/download                  │" -ForegroundColor Cyan
    Write-Host "│ 2. Extract & Run the .exe                                │" -ForegroundColor Cyan
    Write-Host "│ 3. Run: ngrok http 5001                                  │" -ForegroundColor Cyan
    Write-Host "│ 4. Copy Forwarding URL (https://...) to BASE_URL         │" -ForegroundColor Cyan
    Write-BoxFooter
}

# -----------------------------------------------------------------------------
# OPTION 1: FULL SETUP
# -----------------------------------------------------------------------------
function Run-FullSetup {
    Write-Header "Full / Initial Setup"
    Check-Dependencies

    Write-Header "Step 2: Configuration"
    $MONGODB_URI = Get-Input "MongoDB URI" "mongodb://localhost:27017/intellicall-ai"
    $BACKEND_PORT = Get-Input "Backend API Port" "5001"

    if (-not (Test-MongoDB $MONGODB_URI)) {
        Write-Error "Cannot connect to MongoDB at $MONGODB_URI"
        return
    }
    Write-Success "MongoDB connection successful!"

    Write-Step "Authentication Setup"
    Write-Info "Google OAuth is used for login."
    $GOOGLE_ID = Get-Input "Google Client ID" "your_google_client_id"
    $GOOGLE_SECRET = Get-Input "Google Client Secret" "your_google_client_secret"
    
    Write-Step "URLs Configuration"
    Write-Info "Twilio needs a PUBLIC URL to send voice streams to your machine."
    $wantNgrok = Read-Host "  Do you need help setting up ngrok for local testing? [y/N]"
    if ($wantNgrok -match "[Yy]") {
        Write-NgrokInfo
    }
    
    $BASE_URL = Get-Input "Backend Base URL (URL of THIS machine)" "http://localhost:5001"
    $CLIENT_URL = Get-Input "Frontend Client URL" "http://localhost:3000"

    Write-Step "Generating secure JWT secret..."
    $JWT_SECRET = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | ForEach-Object {[char]$_})
    Write-Success "JWT secret generated."

    # Backend .env
    Write-Header "Step 3: Configuring Backend & Core API"
    Write-Info "Creating backend environment configuration..."
    Backup-File "$BackendDir\.env"
    $BackendEnv = @"
# IntelliCall AI Backend Configuration
PORT=$BACKEND_PORT
MONGODB_URI=$MONGODB_URI
NODE_ENV=development
JWT_SECRET=$JWT_SECRET
BASE_URL=$BASE_URL

# Google OAuth
GOOGLE_CLIENT_ID=$GOOGLE_ID
GOOGLE_CLIENT_SECRET=$GOOGLE_SECRET
CLIENT_URL=$CLIENT_URL
"@
    $BackendEnv | Out-File -FilePath "$BackendDir\.env" -Encoding utf8
    Write-Success "Backend .env created"

    Write-Step "Installing backend dependencies (this may take a minute)..."
    try {
        Set-Location $BackendDir
        npm install --silent 2>$null
        Write-Success "Backend dependencies installed"
    } catch {
        Write-Warning "Automated backend installation skipped/failed."
        Write-Info "Please run 'npm install' manually in the 'backend' folder later."
    }

    # Frontend .env
    Write-Header "Step 4: Configuring Frontend Dashboard"
    Write-Info "Connecting frontend to backend API..."
    Backup-File "$FrontendDir\.env"
    $FrontendEnv = @"
# IntelliCall AI Frontend Configuration
NEXT_PUBLIC_API_URL=$BASE_URL/api
"@
    $FrontendEnv | Out-File -FilePath "$FrontendDir\.env" -Encoding utf8
    Write-Success "Frontend .env created"

    Write-Step "Installing frontend dependencies (this may take a minute)..."
    try {
        Set-Location $FrontendDir
        npm install --silent 2>$null
        Write-Success "Frontend dependencies installed"
    } catch {
        Write-Warning "Automated frontend installation skipped/failed."
        Write-Info "Please run 'npm install' manually in the 'frontend' folder later."
    }

    # Runtime Validation
    Write-Header "Step 5: Starting Backend & Validation"
    Write-Step "Starting backend server..."
    Set-Location $BackendDir
    $BackendJob = Start-Job -ScriptBlock {
        param($path)
        Set-Location $path
        npm run start
    } -ArgumentList $BackendDir
    Start-Sleep -Seconds 8

    Write-Step "Verifying backend connection..."
    $MaxRetries = 15
    $RetryCount = 0
    $BackendOK = $false
    while ($RetryCount -lt $MaxRetries) {
        try {
            $resp = Invoke-RestMethod -Uri "http://localhost:$BACKEND_PORT/health" -Method Get -TimeoutSec 5
            if ($resp.status -eq "success") { $BackendOK = $true; break }
        } catch {}
        $RetryCount++
        Start-Sleep -Seconds 2
    }

    Stop-Job $BackendJob -ErrorAction SilentlyContinue
    if ($BackendOK) { Write-Success "Backend server validated successfully!" }
    else { 
        Write-Warning "Backend validation skipped or failed."
        Write-Info "Don't worry, you can still start the server manually for debugging."
    }

    Write-Header "🎉 Full Setup Complete!"
    
    Write-Box "🚀 NEXT STEPS TO GET STARTED"
    Write-Host "│ 1. Open TWO terminal windows.                              │" -ForegroundColor Cyan
    Write-Host "│ 2. In Window 1 (Backend):                                  │" -ForegroundColor Cyan
    Write-Host "│    cd backend; npm run dev                                 │" -ForegroundColor Cyan
    Write-Host "│ 3. In Window 2 (Frontend):                                 │" -ForegroundColor Cyan
    Write-Host "│    cd frontend; npm run dev                                │" -ForegroundColor Cyan
    Write-Host "│ 4. Open http://localhost:3000 in your browser.             │" -ForegroundColor Cyan
    Write-Host "│ 5. Sign in via Google. First user is automatically ADMIN.  │" -ForegroundColor Cyan
    Write-BoxFooter
    
    Write-Host ""
    Write-Info "Need help? Check the Documentation/QuickStart.html file."
    Write-Success "IntelliCall AI is now configured and ready for production logic!"
}

# -----------------------------------------------------------------------------
# OPTION 2: FRONTEND CUSTOMIZATION
# -----------------------------------------------------------------------------
function Customize-Frontend {
    Write-Header "Frontend Customization (Next.js)"
    $EnvFile = "$FrontendDir\.env"
    if (-not (Test-Path $EnvFile)) { Write-Warning "Run Full Setup first."; return }

    $lines = Get-Content $EnvFile
    $CurrentAPI = ($lines | Select-String "NEXT_PUBLIC_API_URL=").ToString().Split('=')[1]

    $API_URL = Get-Input "Backend API URL" $CurrentAPI

    Backup-File $EnvFile
    Update-EnvVar $EnvFile "NEXT_PUBLIC_API_URL" $API_URL
    
    Write-Success "Frontend configuration updated!"
}

# -----------------------------------------------------------------------------
# OPTION 3: BACKEND CUSTOMIZATION
# -----------------------------------------------------------------------------
function Customize-Backend {
    Write-Header "Backend Customization (Node.js)"
    $EnvFile = "$BackendDir\.env"
    if (-not (Test-Path $EnvFile)) { Write-Warning "Run Full Setup first."; return }

    Write-Info "Keep current values by pressing Enter."
    
    $CurrentEnv = @{}
    foreach ($line in Get-Content $EnvFile) {
        if ($line -match "^([^#\s][^=]*)=(.*)$") {
            $CurrentEnv[$Matches[1]] = $Matches[2]
        }
    }

    $NEW_PORT = Get-Input "API Port" $CurrentEnv["PORT"]
    $NEW_MONGO = Get-Input "MongoDB URI" $CurrentEnv["MONGODB_URI"]
    $NEW_GOOGLE_ID = Get-Input "Google Client ID" $CurrentEnv["GOOGLE_CLIENT_ID"]
    $NEW_GOOGLE_SECRET = Get-Input "Google Client Secret" $CurrentEnv["GOOGLE_CLIENT_SECRET"]
    $NEW_BASE_URL = Get-Input "Base URL" $CurrentEnv["BASE_URL"]
    $NEW_CLIENT_URL = Get-Input "Client URL" $CurrentEnv["CLIENT_URL"]

    Backup-File $EnvFile
    Update-EnvVar $EnvFile "PORT" $NEW_PORT
    Update-EnvVar $EnvFile "MONGODB_URI" $NEW_MONGO
    Update-EnvVar $EnvFile "GOOGLE_CLIENT_ID" $NEW_GOOGLE_ID
    Update-EnvVar $EnvFile "GOOGLE_CLIENT_SECRET" $NEW_GOOGLE_SECRET
    Update-EnvVar $EnvFile "BASE_URL" $NEW_BASE_URL
    Update-EnvVar $EnvFile "CLIENT_URL" $NEW_CLIENT_URL

    # Sync Frontend API URL if Base URL changed
    if ($NEW_BASE_URL -ne $CurrentEnv["BASE_URL"]) {
        $FeEnv = "$FrontendDir\.env"
        if (Test-Path $FeEnv) {
            Write-Step "Syncing Frontend API URL..."
            Update-EnvVar $FeEnv "NEXT_PUBLIC_API_URL" "$NEW_BASE_URL/api"
        }
    }

    Write-Success "Backend configuration updated!"
}

# -----------------------------------------------------------------------------
# MAIN LOOP
# -----------------------------------------------------------------------------
while ($true) {
    Clear-Host
    Write-Host "  IntelliCall AI Setup" -ForegroundColor Cyan
    Write-Host ""
    Write-Host "  IntelliCall AI Ultimate Setup & Customization Wizard (Windows)" -ForegroundColor White
    Write-Host "  ========================================================="
    Write-Host "  1) Full / Initial Setup (Recommended)"
    Write-Host "  2) Frontend Customization (Next.js)"
    Write-Host "  3) Backend Customization (Node.js)"
    Write-Host "  4) Exit"
    Write-Host "  ========================================================="
    Write-Host ""
    
    $choice = Read-Host "  Select option [1-4]"
    
    switch ($choice) {
        "1" { Run-FullSetup }
        "2" { Customize-Frontend }
        "3" { Customize-Backend }
        "4" { Write-Info "Exiting. Goodbye!"; exit }
        default { Write-Error "Invalid choice." }
    }
    
    Write-Host ""
    Read-Host "  Press Enter to return to menu..."
}
