package hdmistat

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

	"github.com/spf13/cobra"
)

// newInstallCmd creates the install command
func (c *CLI) newInstallCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "install",
		Short: "Install hdmistat as a systemd service",
		Long:  `Install hdmistat as a systemd service that starts automatically on boot.`,
		Run:   c.runInstall,
	}
}

const systemdUnit = `[Unit]
Description=HDMI Statistics Display Daemon
After=multi-user.target
Conflicts=getty@tty1.service

[Service]
Type=simple
ExecStart=%s daemon
Restart=always
RestartSec=10
StandardOutput=journal+console
StandardError=journal+console
SyslogIdentifier=hdmistat
Environment="HDMISTAT_LOG_LEVEL=debug"
Environment="GOTRACEBACK=all"

[Install]
WantedBy=multi-user.target
`

func (c *CLI) runInstall(_ *cobra.Command, _ []string) {
	// Check if running as root
	if os.Geteuid() != 0 {
		c.log.Error("install command must be run as root")
		os.Exit(1)
	}

	// Find hdmistat binary in PATH
	hdmistatPath, err := exec.LookPath("hdmistat")
	if err != nil {
		c.log.Error("hdmistat not found in PATH", "error", err)
		os.Exit(1)
	}

	// Get absolute path
	hdmistatPath, err = filepath.Abs(hdmistatPath)
	if err != nil {
		c.log.Error("getting absolute path", "error", err)
		os.Exit(1)
	}

	c.log.Info("found hdmistat binary", "path", hdmistatPath)

	// Create systemd unit file
	unitContent := fmt.Sprintf(systemdUnit, hdmistatPath)
	unitPath := "/etc/systemd/system/hdmistat.service"

	const fileMode = 0600
	err = os.WriteFile(unitPath, []byte(unitContent), fileMode)
	if err != nil {
		c.log.Error("writing systemd unit file", "error", err)
		os.Exit(1)
	}

	c.log.Info("created systemd unit file", "path", unitPath)

	// Create config directory
	configDir := "/etc/hdmistat"
	const dirMode = 0750
	err = os.MkdirAll(configDir, dirMode)
	if err != nil {
		c.log.Error("creating config directory", "error", err)
		os.Exit(1)
	}

	// Create default config if it doesn't exist
	configPath := filepath.Join(configDir, "config.yaml")
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		defaultConfig := `# hdmistat configuration file
# This file is optional - hdmistat will use sensible defaults if not present
# Uncomment and modify any settings you want to override

# Framebuffer device to use for display
#framebuffer_device: /dev/fb0

# How often to rotate between screens
#rotation_interval: 10s

# How often to update the current screen
#update_interval: 1s

# Log level: debug, info, warn, error
#log_level: info

# Display resolution (auto-detected from framebuffer if not set)
#width: 1920
#height: 1080

# Screens to display in rotation order
#screens:
#  - overview
#  - top_cpu
#  - top_memory
`
		const configFileMode = 0600
		err = os.WriteFile(configPath, []byte(defaultConfig), configFileMode)
		if err != nil {
			c.log.Error("writing default config", "error", err)
			os.Exit(1)
		}
		c.log.Info("created default config", "path", configPath)
	}

	// Reload systemd
	c.log.Info("reloading systemd daemon")
	if err := exec.Command("systemctl", "daemon-reload").Run(); err != nil {
		c.log.Error("reloading systemd", "error", err)
		os.Exit(1)
	}

	// Enable service
	c.log.Info("enabling hdmistat service")
	if err := exec.Command("systemctl", "enable", "hdmistat.service").Run(); err != nil {
		c.log.Error("enabling service", "error", err)
		os.Exit(1)
	}

	// Start service
	c.log.Info("starting hdmistat service")
	if err := exec.Command("systemctl", "start", "hdmistat.service").Run(); err != nil {
		c.log.Error("starting service", "error", err)
		os.Exit(1)
	}

	c.log.Info("hdmistat service installed and started successfully")
	fmt.Println("\nhdmistat has been installed as a systemd service.")
	fmt.Println("You can check the status with: systemctl status hdmistat")
	fmt.Println("View logs with: journalctl -u hdmistat -f")
}
