package system

import (
	"net/http"
	"strconv"

	"github.com/atlasos/calypso/internal/common/logger"
	"github.com/atlasos/calypso/internal/tasks"
	"github.com/gin-gonic/gin"
)

// Handler handles system management API requests
type Handler struct {
	service    *Service
	taskEngine *tasks.Engine
	logger     *logger.Logger
}

// NewHandler creates a new system handler
func NewHandler(log *logger.Logger, taskEngine *tasks.Engine) *Handler {
	return &Handler{
		service:    NewService(log),
		taskEngine: taskEngine,
		logger:     log,
	}
}

// ListServices lists all system services
func (h *Handler) ListServices(c *gin.Context) {
	services, err := h.service.ListServices(c.Request.Context())
	if err != nil {
		h.logger.Error("Failed to list services", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to list services"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"services": services})
}

// GetServiceStatus retrieves status of a specific service
func (h *Handler) GetServiceStatus(c *gin.Context) {
	serviceName := c.Param("name")

	status, err := h.service.GetServiceStatus(c.Request.Context(), serviceName)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "service not found"})
		return
	}

	c.JSON(http.StatusOK, status)
}

// RestartService restarts a system service
func (h *Handler) RestartService(c *gin.Context) {
	serviceName := c.Param("name")

	if err := h.service.RestartService(c.Request.Context(), serviceName); err != nil {
		h.logger.Error("Failed to restart service", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "service restarted successfully"})
}

// GetServiceLogs retrieves journald logs for a service
func (h *Handler) GetServiceLogs(c *gin.Context) {
	serviceName := c.Param("name")
	linesStr := c.DefaultQuery("lines", "100")
	lines, err := strconv.Atoi(linesStr)
	if err != nil {
		lines = 100
	}

	logs, err := h.service.GetJournalLogs(c.Request.Context(), serviceName, lines)
	if err != nil {
		h.logger.Error("Failed to get logs", "error", err)
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to get logs"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"logs": logs})
}

// GenerateSupportBundle generates a diagnostic support bundle
func (h *Handler) GenerateSupportBundle(c *gin.Context) {
	userID, _ := c.Get("user_id")

	// Create async task
	taskID, err := h.taskEngine.CreateTask(c.Request.Context(),
		tasks.TaskTypeSupportBundle, userID.(string), map[string]interface{}{
			"operation": "generate_support_bundle",
		})
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to create task"})
		return
	}

	// Run bundle generation in background
	go func() {
		ctx := c.Request.Context()
		h.taskEngine.StartTask(ctx, taskID)
		h.taskEngine.UpdateProgress(ctx, taskID, 50, "Collecting system information...")

		outputPath := "/tmp/calypso-support-bundle-" + taskID
		if err := h.service.GenerateSupportBundle(ctx, outputPath); err != nil {
			h.taskEngine.FailTask(ctx, taskID, err.Error())
			return
		}

		h.taskEngine.UpdateProgress(ctx, taskID, 100, "Support bundle generated")
		h.taskEngine.CompleteTask(ctx, taskID, "Support bundle generated successfully")
	}()

	c.JSON(http.StatusAccepted, gin.H{"task_id": taskID})
}

