package service

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// LinuxServiceManager Linux服务管理器
type LinuxServiceManager struct {
	*BaseServiceManager
	serviceFilePath string
	useSudo         bool
	systemdUser     bool
}

// NewLinuxServiceManager 创建Linux服务管理器
func NewLinuxServiceManager(detector *PlatformDetector) *LinuxServiceManager {
	info := detector.GetPlatformInfo()
	base := &BaseServiceManager{
		detector: detector,
		config:   createDefaultServiceConfig(detector),
	}

	// 确定服务文件路径
	var serviceFilePath string
	var useSudo, systemdUser bool

	if info.ServiceMgr == ServiceMgr_Systemd && info.UserLevel {
		// 用户级systemd服务
		homeDir, _ := os.UserHomeDir()
		serviceFilePath = filepath.Join(homeDir, ".config", "systemd", "user", base.config.ServiceName+".service")
		systemdUser = true
		useSudo = false
	} else {
		// 系统级服务
		serviceFilePath = "/etc/systemd/system/" + base.config.ServiceName + ".service"
		useSudo = true
		systemdUser = false
	}

	return &LinuxServiceManager{
		BaseServiceManager: base,
		serviceFilePath:    serviceFilePath,
		useSudo:            useSudo,
		systemdUser:        systemdUser,
	}
}

// InstallService 安装systemd服务
func (l *LinuxServiceManager) InstallService() error {
	info := l.GetPlatformInfo()

	// 验证可执行文件路径
	if err := checkExecutablePath(l.config.ExecPath); err != nil {
		return fmt.Errorf("可执行文件路径验证失败: %v", err)
	}

	// 确保服务目录存在
	serviceDir := filepath.Dir(l.serviceFilePath)
	if err := os.MkdirAll(serviceDir, 0755); err != nil {
		return fmt.Errorf("创建服务目录失败: %v", err)
	}

	// 确保日志目录存在
	if err := ensureLogDirectory(l.config.LogFile); err != nil {
		return fmt.Errorf("创建日志目录失败: %v", err)
	}

	// 生成systemd服务文件
	serviceContent := l.generateSystemdServiceFile()
	if err := os.WriteFile(l.serviceFilePath, []byte(serviceContent), 0644); err != nil {
		return fmt.Errorf("写入服务文件失败: %v", err)
	}

	// 重新加载systemd配置
	reloadCmd := []string{"systemctl", "daemon-reload"}
	if l.systemdUser {
		reloadCmd = []string{"systemctl", "--user", "daemon-reload"}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(reloadCmd[0], reloadCmd[1:]...)
	} else {
		_, err = runCommand(reloadCmd[0], reloadCmd[1:]...)
	}

	if err != nil {
		// 清理已创建的文件
		os.Remove(l.serviceFilePath)
		return fmt.Errorf("重新加载systemd配置失败: %v", err)
	}

	fmt.Printf("✅ Linux systemd服务安装成功\n")
	fmt.Printf("   服务文件: %s\n", l.serviceFilePath)
	fmt.Printf("   服务名称: %s\n", l.config.ServiceName)
	fmt.Printf("   日志文件: %s\n", l.config.LogFile)

	if l.systemdUser {
		fmt.Printf("   提示: 用户级服务，用户登录时自动启动\n")
		fmt.Printf("   管理命令: systemctl --user %s\n", l.config.ServiceName)
	} else {
		fmt.Printf("   提示: 系统级服务，开机时自动启动\n")
		fmt.Printf("   管理命令: sudo systemctl %s\n", l.config.ServiceName)
	}

	if info.ServiceMgr == ServiceMgr_Systemd {
		fmt.Printf("   服务管理器: systemd\n")
	} else {
		fmt.Printf("   服务管理器: SysVInit\n")
	}

	return nil
}

// UninstallService 卸载systemd服务
func (l *LinuxServiceManager) UninstallService() error {
	if !l.IsServiceInstalled() {
		return fmt.Errorf("服务未安装")
	}

	// 停止服务
	l.StopService()

	// 禁用服务
	l.DisableAutostart()

	// 删除服务文件
	if err := os.Remove(l.serviceFilePath); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("删除服务文件失败: %v", err)
	}

	// 重新加载systemd配置
	reloadCmd := []string{"systemctl", "daemon-reload"}
	if l.systemdUser {
		reloadCmd = []string{"systemctl", "--user", "daemon-reload"}
	}

	if l.useSudo {
		runCommandWithSudo(reloadCmd[0], reloadCmd[1:]...)
	} else {
		runCommand(reloadCmd[0], reloadCmd[1:]...)
	}

	fmt.Printf("✅ Linux systemd服务卸载成功\n")
	fmt.Printf("   已删除服务文件: %s\n", l.serviceFilePath)

	return nil
}

// StartService 启动服务
func (l *LinuxServiceManager) StartService() error {
	if !l.IsServiceInstalled() {
		return fmt.Errorf("服务未安装，请先安装服务")
	}

	if l.IsServiceRunning() {
		fmt.Printf("⚠️ 服务已在运行中\n")
		return nil
	}

	startCmd := []string{"systemctl", "start", l.config.ServiceName}
	if l.systemdUser {
		startCmd = []string{"systemctl", "--user", "start", l.config.ServiceName}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(startCmd[0], startCmd[1:]...)
	} else {
		_, err = runCommand(startCmd[0], startCmd[1:]...)
	}

	if err != nil {
		return fmt.Errorf("启动服务失败: %v", err)
	}

	fmt.Printf("✅ 服务启动成功\n")
	return nil
}

// StopService 停止服务
func (l *LinuxServiceManager) StopService() error {
	if !l.IsServiceInstalled() {
		return fmt.Errorf("服务未安装")
	}

	if !l.IsServiceRunning() {
		fmt.Printf("⚠️ 服务未在运行\n")
		return nil
	}

	stopCmd := []string{"systemctl", "stop", l.config.ServiceName}
	if l.systemdUser {
		stopCmd = []string{"systemctl", "--user", "stop", l.config.ServiceName}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(stopCmd[0], stopCmd[1:]...)
	} else {
		_, err = runCommand(stopCmd[0], stopCmd[1:]...)
	}

	if err != nil {
		return fmt.Errorf("停止服务失败: %v", err)
	}

	fmt.Printf("✅ 服务停止成功\n")
	return nil
}

// RestartService 重启服务
func (l *LinuxServiceManager) RestartService() error {
	restartCmd := []string{"systemctl", "restart", l.config.ServiceName}
	if l.systemdUser {
		restartCmd = []string{"systemctl", "--user", "restart", l.config.ServiceName}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(restartCmd[0], restartCmd[1:]...)
	} else {
		_, err = runCommand(restartCmd[0], restartCmd[1:]...)
	}

	if err != nil {
		return fmt.Errorf("重启服务失败: %v", err)
	}

	fmt.Printf("✅ 服务重启成功\n")
	return nil
}

// IsServiceInstalled 检查服务是否已安装
func (l *LinuxServiceManager) IsServiceInstalled() bool {
	_, err := os.Stat(l.serviceFilePath)
	return err == nil
}

// IsServiceRunning 检查服务是否正在运行
func (l *LinuxServiceManager) IsServiceRunning() bool {
	statusCmd := []string{"systemctl", "is-active", l.config.ServiceName}
	if l.systemdUser {
		statusCmd = []string{"systemctl", "--user", "is-active", l.config.ServiceName}
	}

	output, err := runCommand(statusCmd[0], statusCmd[1:]...)
	if err != nil {
		return false
	}

	return strings.Contains(strings.TrimSpace(output), "active")
}

// GetServiceStatus 获取服务状态
func (l *LinuxServiceManager) GetServiceStatus() *ServiceStatus {
	status := &ServiceStatus{
		Platform:     "Linux",
		ServiceName:  l.config.ServiceName,
		IsInstalled:  l.IsServiceInstalled(),
		IsRunning:    l.IsServiceRunning(),
		Autostart:    l.IsAutostartEnabled(),
		LastModified: time.Now(),
	}

	if status.IsInstalled {
		if info, err := os.Stat(l.serviceFilePath); err == nil {
			status.LastModified = info.ModTime()
		}

		// 获取详细状态信息
		if detailedStatus := l.getDetailedServiceStatus(); detailedStatus != "" {
			status.Status = detailedStatus
		}

		// 获取PID和运行时长
		if status.IsRunning {
			if pid := l.getServicePID(); pid > 0 {
				status.Pid = pid
				status.Uptime = l.getServiceUptime(pid)
			}
		}
	}

	return status
}

// getDetailedServiceStatus 获取详细服务状态
func (l *LinuxServiceManager) getDetailedServiceStatus() string {
	statusCmd := []string{"systemctl", "status", l.config.ServiceName}
	if l.systemdUser {
		statusCmd = []string{"systemctl", "--user", "status", l.config.ServiceName}
	}

	output, err := runCommand(statusCmd[0], statusCmd[1:]...)
	if err != nil {
		return ""
	}

	// 提取关键状态信息
	lines := strings.Split(strings.TrimSpace(output), "\n")
	if len(lines) > 0 {
		for _, line := range lines {
			if strings.Contains(line, "Active:") {
				return strings.TrimSpace(line)
			}
		}
	}

	return ""
}

// getServicePID 获取服务进程ID
func (l *LinuxServiceManager) getServicePID() int {
	statusCmd := []string{"systemctl", "show", l.config.ServiceName, "--property=MainPID"}
	if l.systemdUser {
		statusCmd = []string{"systemctl", "--user", "show", l.config.ServiceName, "--property=MainPID"}
	}

	output, err := runCommand(statusCmd[0], statusCmd[1:]...)
	if err != nil {
		return 0
	}

	lines := strings.Split(strings.TrimSpace(output), "\n")
	for _, line := range lines {
		if strings.HasPrefix(line, "MainPID=") {
			pidStr := strings.TrimPrefix(line, "MainPID=")
			if pid, err := strconv.Atoi(pidStr); err == nil {
				return pid
			}
		}
	}

	return 0
}

// getServiceUptime 获取服务运行时长
func (l *LinuxServiceManager) getServiceUptime(pid int) string {
	// 使用systemctl show获取运行时长
	showCmd := []string{"systemctl", "show", l.config.ServiceName, "--property=ActiveEnterTimestamp"}
	if l.systemdUser {
		showCmd = []string{"systemctl", "--user", "show", l.config.ServiceName, "--property=ActiveEnterTimestamp"}
	}

	output, err := runCommand(showCmd[0], showCmd[1:]...)
	if err != nil {
		return ""
	}

	lines := strings.Split(strings.TrimSpace(output), "\n")
	for _, line := range lines {
		if strings.HasPrefix(line, "ActiveEnterTimestamp=") {
			timestampStr := strings.TrimPrefix(line, "ActiveEnterTimestamp=")
			// 解析时间戳 (格式: 2025-01-01 12:00:00)
			if startTime, err := time.Parse("2006-01-02 15:04:05", timestampStr); err == nil {
				uptime := time.Since(startTime)
				days := int(uptime.Hours()) / 24
				hours := int(uptime.Hours()) % 24
				minutes := int(uptime.Minutes()) % 60

				if days > 0 {
					return fmt.Sprintf("%d天%d小时%d分钟", days, hours, minutes)
				} else if hours > 0 {
					return fmt.Sprintf("%d小时%d分钟", hours, minutes)
				} else {
					return fmt.Sprintf("%d分钟", minutes)
				}
			}
		}
	}

	return ""
}

// EnableAutostart 启用开机自启
func (l *LinuxServiceManager) EnableAutostart() error {
	if !l.IsServiceInstalled() {
		return fmt.Errorf("服务未安装")
	}

	enableCmd := []string{"systemctl", "enable", l.config.ServiceName}
	if l.systemdUser {
		enableCmd = []string{"systemctl", "--user", "enable", l.config.ServiceName}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(enableCmd[0], enableCmd[1:]...)
	} else {
		_, err = runCommand(enableCmd[0], enableCmd[1:]...)
	}

	if err != nil {
		return fmt.Errorf("启用开机自启失败: %v", err)
	}

	fmt.Printf("✅ 已启用开机自启\n")
	return nil
}

// DisableAutostart 禁用开机自启
func (l *LinuxServiceManager) DisableAutostart() error {
	if !l.IsServiceInstalled() {
		return fmt.Errorf("服务未安装")
	}

	disableCmd := []string{"systemctl", "disable", l.config.ServiceName}
	if l.systemdUser {
		disableCmd = []string{"systemctl", "--user", "disable", l.config.ServiceName}
	}

	var err error
	if l.useSudo {
		_, err = runCommandWithSudo(disableCmd[0], disableCmd[1:]...)
	} else {
		_, err = runCommand(disableCmd[0], disableCmd[1:]...)
	}

	if err != nil {
		return fmt.Errorf("禁用开机自启失败: %v", err)
	}

	fmt.Printf("✅ 已禁用开机自启\n")
	return nil
}

// IsAutostartEnabled 检查开机自启是否启用
func (l *LinuxServiceManager) IsAutostartEnabled() bool {
	if !l.IsServiceInstalled() {
		return false
	}

	isEnabledCmd := []string{"systemctl", "is-enabled", l.config.ServiceName}
	if l.systemdUser {
		isEnabledCmd = []string{"systemctl", "--user", "is-enabled", l.config.ServiceName}
	}

	output, err := runCommand(isEnabledCmd[0], isEnabledCmd[1:]...)
	if err != nil {
		return false
	}

	return strings.Contains(strings.TrimSpace(output), "enabled")
}

// GetServiceLogs 获取服务日志
func (l *LinuxServiceManager) GetServiceLogs(lines int) ([]string, error) {
	journalCmd := []string{"journalctl", "-u", l.config.ServiceName, "-n", fmt.Sprintf("%d", lines)}
	if l.systemdUser {
		journalCmd = []string{"journalctl", "--user", "-u", l.config.ServiceName, "-n", fmt.Sprintf("%d", lines)}
	}

	output, err := runCommand(journalCmd[0], journalCmd[1:]...)
	if err != nil {
		return nil, fmt.Errorf("读取日志失败: %v", err)
	}

	if output == "" {
		return []string{"暂无日志"}, nil
	}

	return strings.Split(strings.TrimSpace(output), "\n"), nil
}

// FollowLogs 实时跟踪日志
func (l *LinuxServiceManager) FollowLogs() error {
	fmt.Printf("📋 实时跟踪服务日志 (按Ctrl+C退出):\n")
	fmt.Printf("   服务名称: %s\n", l.config.ServiceName)
	if l.systemdUser {
		fmt.Printf("   日志命令: journalctl --user -u %s -f\n", l.config.ServiceName)
	} else {
		fmt.Printf("   日志命令: journalctl -u %s -f\n", l.config.ServiceName)
	}
	fmt.Printf("------------------------------------------------------------\n")

	// 使用journalctl -f实时跟踪日志
	journalCmd := []string{"journalctl", "-u", l.config.ServiceName, "-f"}
	if l.systemdUser {
		journalCmd = []string{"journalctl", "--user", "-u", l.config.ServiceName, "-f"}
	}

	cmd := exec.Command(journalCmd[0], journalCmd[1:]...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	return cmd.Run()
}

// generateSystemdServiceFile 生成systemd服务文件内容
func (l *LinuxServiceManager) generateSystemdServiceFile() string {
	wantedBy := "multi-user.target"
	if l.systemdUser {
		wantedBy = "default.target"
	}

	userSection := ""
	if !l.systemdUser {
		// 系统级服务需要指定用户
		userSection = fmt.Sprintf("User=%s\nGroup=%s\n", os.Getenv("USER"), os.Getenv("USER"))
	}

	return fmt.Sprintf(`[Unit]
Description=%s
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
%sExecStart=%s %s
Restart=always
RestartSec=10
WorkingDirectory=%s
StandardOutput=append:%s
StandardError=append:%s
Environment=GIN_MODE=release

[Install]
WantedBy=%s`,
		l.config.Description,
		userSection,
		l.config.ExecPath,
		strings.Join(l.config.Args, " "),
		l.config.WorkingDir,
		l.config.LogFile,
		l.config.ErrorFile,
		wantedBy)
}
