package handlers

import (
	"fmt"
	"net/http"

	"github.com/Fimeg/RedFlag/aggregator-server/internal/services"
	"github.com/gin-gonic/gin"
)

// NewAgentBuild handles new agent installation requests
// Deprecated: Use AgentHandler.Upgrade instead
func NewAgentBuild(c *gin.Context) {
	var req services.NewBuildRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Validate registration token
	if req.RegistrationToken == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "registration token is required for new installations"})
		return
	}

	// Convert to setup request format
	setupReq := services.AgentSetupRequest{
		ServerURL:     req.ServerURL,
		Environment:   req.Environment,
		AgentType:     req.AgentType,
		Organization:  req.Organization,
		CustomSettings: req.CustomSettings,
		DeploymentID:  req.DeploymentID,
	}

	// Create config builder
	configBuilder := services.NewConfigBuilder(req.ServerURL, nil)

	// Build agent configuration
	config, err := configBuilder.BuildAgentConfig(setupReq)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Override generated agent ID if provided (for upgrades)
	if req.AgentID != "" {
		config.AgentID = req.AgentID
		// Update public config with existing agent ID
		if config.PublicConfig == nil {
			config.PublicConfig = make(map[string]interface{})
		}
		config.PublicConfig["agent_id"] = req.AgentID
	}

	// Create agent builder
	agentBuilder := services.NewAgentBuilder()

	// Generate build artifacts
	buildResult, err := agentBuilder.BuildAgentWithConfig(config)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Construct download URL
	binaryURL := fmt.Sprintf("%s/api/v1/downloads/%s", req.ServerURL, config.Platform)

	// Create response with native binary instructions
	response := gin.H{
		"agent_id":        config.AgentID,
		"binary_url":      binaryURL,
		"platform":        config.Platform,
		"config_version":  config.ConfigVersion,
		"agent_version":   config.AgentVersion,
		"build_time":      buildResult.BuildTime,
		"install_type":    "new",
		"consumes_seat":   true,
		"next_steps": []string{
			"1. Download native binary: curl -sL " + binaryURL + " -o /usr/local/bin/redflag-agent",
			"2. Set permissions: chmod 755 /usr/local/bin/redflag-agent",
			"3. Create config directory: mkdir -p /etc/redflag",
			"4. Save configuration (provided in this response) to /etc/redflag/config.json",
			"5. Set config permissions: chmod 600 /etc/redflag/config.json",
			"6. Start service: systemctl enable --now redflag-agent",
		},
		"configuration": config.PublicConfig,
	}

	c.JSON(http.StatusOK, response)
}

// UpgradeAgentBuild handles agent upgrade requests
// Deprecated: Use ConfigService for config building
func UpgradeAgentBuild(c *gin.Context) {
	agentID := c.Param("agentID")
	if agentID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "agent ID is required"})
		return
	}

	var req services.UpgradeBuildRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Validate required fields
	if req.ServerURL == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "server URL is required"})
		return
	}

	// Convert to setup request format
	setupReq := services.AgentSetupRequest{
		ServerURL:     req.ServerURL,
		Environment:   req.Environment,
		AgentType:     req.AgentType,
		Organization:  req.Organization,
		CustomSettings: req.CustomSettings,
		DeploymentID:  req.DeploymentID,
	}

	// Create config builder
	configBuilder := services.NewConfigBuilder(req.ServerURL, nil)

	// Build agent configuration
	config, err := configBuilder.BuildAgentConfig(setupReq)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Override with existing agent ID (this is the key for upgrades)
	config.AgentID = agentID
	if config.PublicConfig == nil {
		config.PublicConfig = make(map[string]interface{})
	}
	config.PublicConfig["agent_id"] = agentID

	// For upgrades, we might want to preserve certain existing settings
	if req.PreserveExisting {
		// TODO: Load existing agent config and merge/override as needed
		// This would involve reading the existing agent's configuration
		// and selectively preserving certain fields
	}

	// Create agent builder
	agentBuilder := services.NewAgentBuilder()

	// Generate build artifacts
	buildResult, err := agentBuilder.BuildAgentWithConfig(config)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// Construct download URL
	binaryURL := fmt.Sprintf("%s/api/v1/downloads/%s?version=%s", req.ServerURL, config.Platform, config.AgentVersion)

	// Create response with native binary upgrade instructions
	response := gin.H{
		"agent_id":           config.AgentID,
		"binary_url":         binaryURL,
		"platform":           config.Platform,
		"config_version":     config.ConfigVersion,
		"agent_version":      config.AgentVersion,
		"build_time":         buildResult.BuildTime,
		"install_type":       "upgrade",
		"consumes_seat":      false,
		"preserves_agent_id": true,
		"next_steps": []string{
			"1. Stop agent service: systemctl stop redflag-agent",
			"2. Download updated binary: curl -sL " + binaryURL + " -o /usr/local/bin/redflag-agent",
			"3. Set permissions: chmod 755 /usr/local/bin/redflag-agent",
			"4. Update config (provided in this response) to /etc/redflag/config.json if needed",
			"5. Start service: systemctl start redflag-agent",
			"6. Verify: systemctl status redflag-agent",
		},
		"configuration": config.PublicConfig,
		"upgrade_notes": []string{
			"This upgrade preserves the existing agent ID: " + agentID,
			"No additional seat will be consumed",
			"Config version: " + config.ConfigVersion,
			"Agent binary version: " + config.AgentVersion,
			"Agent will receive latest security enhancements and bug fixes",
		},
	}

	c.JSON(http.StatusOK, response)
}

// DetectAgentInstallation detects existing agent installations
func DetectAgentInstallation(c *gin.Context) {
	// This endpoint helps the installer determine what type of installation to perform
	var req struct {
		AgentID string `json:"agent_id"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// Create detector service
	detector := services.NewInstallationDetector()

	// Detect existing installation
	detection, err := detector.DetectExistingInstallation(req.AgentID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	response := gin.H{
		"detection_result": detection,
		"recommended_action": func() string {
			if detection.HasExistingAgent {
				return "upgrade"
			}
			return "new_installation"
		}(),
		"installation_type": func() string {
			if detection.HasExistingAgent {
				return "upgrade"
			}
			return "new"
		}(),
	}

	c.JSON(http.StatusOK, response)
}