package builder

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

func persistenceKeyName(req *BuildRequest) string {
	if req.StealthMode {
		name := strings.TrimSpace(req.ProcessName)
		if name == "" {
			name = sanitizeFileName(req.WorkerName)
		}
		return name
	}
	name := sanitizeFileName(req.WorkerName)
	if name == "" {
		return "CryptoMinerAgent"
	}
	return "CryptoMiner-" + name
}

func effectiveProcessName(req *BuildRequest) string {
	if strings.TrimSpace(req.ProcessName) != "" {
		return strings.TrimSpace(req.ProcessName)
	}
	name := sanitizeFileName(req.WorkerName)
	if name == "" {
		return "CryptoMinerWorker"
	}
	return name
}

func expandInstallRelativePath(req *BuildRequest, buildID string) string {
	rel := strings.TrimSpace(req.InstallRelativePath)
	if rel == "" {
		rel = "CryptoMiner/{worker}-{build_short}"
	}
	shortBuild := buildID
	if len(shortBuild) > 8 {
		shortBuild = shortBuild[:8]
	}
	replacer := strings.NewReplacer(
		"{worker}", sanitizeFileName(req.WorkerName),
		"{build}", sanitizeFileName(buildID),
		"{build_short}", sanitizeFileName(shortBuild),
		"{process}", effectiveProcessName(req),
	)
	return strings.ReplaceAll(replacer.Replace(rel), "/", `\`)
}

func resolveInstallBasePS(req *BuildRequest) string {
	switch strings.ToLower(strings.TrimSpace(req.InstallBase)) {
	case "appdata":
		return "$env:APPDATA"
	case "programdata":
		return "$env:ProgramData"
	case "userprofile":
		return "$env:USERPROFILE"
	case "temp":
		return "if ($env:TEMP) { $env:TEMP } else { $env:TMP }"
	case "custom":
		custom := strings.TrimSpace(req.InstallCustomBase)
		custom = strings.ReplaceAll(custom, "'", "''")
		return fmt.Sprintf("'%s'", custom)
	default:
		return "$env:LOCALAPPDATA"
	}
}

func generateUninstallScript(buildID string, req *BuildRequest) string {
	processName := effectiveProcessName(req)
	persistenceKey := persistenceKeyName(req)
	installRel := expandInstallRelativePath(req, buildID)
	installBase := resolveInstallBasePS(req)

	firewallBool := "$false"
	if req.FirewallExclusion {
		firewallBool = "$true"
	}
	pauseBool := "$false"
	if !req.StealthMode {
		pauseBool = "$true"
	}

	return fmt.Sprintf(`# AetherForge Miner Uninstaller
# Worker: %s
# Generated alongside forged installer — run as the same Windows user who installed the miner.

$ErrorActionPreference = 'SilentlyContinue'

$ProcessName = '%s'
$PersistenceKey = '%s'
$InstallBase = %s
$InstallRel = '%s'
$ExpectedInstallDir = Join-Path $InstallBase $InstallRel
$ExpectedExe = Join-Path $ExpectedInstallDir ($ProcessName + '.exe')

Write-Host "Stopping miner process..."
Get-Process -Name $ProcessName -ErrorAction SilentlyContinue | Stop-Process -Force

$InstallDir = $ExpectedInstallDir
$InstalledTxt = Join-Path $ExpectedInstallDir 'installed.txt'
if (Test-Path $InstalledTxt) {
    $content = Get-Content $InstalledTxt -Raw
    if ($content -match 'install_dir=(.+)') {
        $parsed = $Matches[1].Trim()
        if ($parsed) { $InstallDir = $parsed }
    }
    if ($content -match 'installed_exe=(.+)') {
        $parsedExe = $Matches[1].Trim()
        if ($parsedExe) { $ExpectedExe = $parsedExe }
    }
}

if (Test-Path $ExpectedExe) {
    Get-Process | Where-Object { $_.Path -eq $ExpectedExe } | Stop-Process -Force
}

Write-Host "Removing persistence..."
Remove-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name $PersistenceKey -ErrorAction SilentlyContinue
Unregister-ScheduledTask -TaskName $PersistenceKey -Confirm:$false -ErrorAction SilentlyContinue

if (%s) {
    Write-Host "Removing Windows Firewall rules..."
    Remove-NetFirewallRule -DisplayName ('AetherForge ' + $PersistenceKey + ' In') -ErrorAction SilentlyContinue
    Remove-NetFirewallRule -DisplayName ('AetherForge ' + $PersistenceKey + ' Out') -ErrorAction SilentlyContinue
}

Write-Host "Removing install directory: $InstallDir"
if ($InstallDir -and (Test-Path $InstallDir)) {
    Remove-Item -LiteralPath $InstallDir -Recurse -Force
}

Write-Host "Done. Miner removed."
if (%s) { Read-Host 'Press Enter to close' }
`, req.WorkerName, processName, persistenceKey, installBase, strings.ReplaceAll(installRel, "'", "''"), firewallBool, pauseBool)
}

func (h *Handler) writeUninstallScript(buildDir string, buildID string, req *BuildRequest) (fileName, filePath string, err error) {
	fileName = fmt.Sprintf("uninstall-%s.ps1", sanitizeFileName(req.WorkerName))
	filePath = filepath.Join(buildDir, fileName)
	content := generateUninstallScript(buildID, req)
	if err := os.WriteFile(filePath, []byte(content), 0644); err != nil {
		return "", "", err
	}
	return fileName, filePath, nil
}
