package command

import (
	"errors"
	"fmt"

	"github.com/google/uuid"
	"github.com/Fimeg/RedFlag/aggregator-server/internal/models"
)

// Validator validates command parameters
type Validator struct {
	minCheckInSeconds int
	maxCheckInSeconds int
	minScannerMinutes int
	maxScannerMinutes int
}

// NewValidator creates a new command validator
func NewValidator() *Validator {
	return &Validator{
		minCheckInSeconds: 60,   // 1 minute minimum
		maxCheckInSeconds: 3600, // 1 hour maximum
		minScannerMinutes: 1,    // 1 minute minimum
		maxScannerMinutes: 1440, // 24 hours maximum
	}
}

// Validate performs comprehensive command validation
func (v *Validator) Validate(cmd *models.AgentCommand) error {
	if cmd == nil {
		return errors.New("command cannot be nil")
	}

	if cmd.ID == uuid.Nil {
		return errors.New("command ID cannot be zero UUID")
	}

	if cmd.AgentID == uuid.Nil {
		return errors.New("agent ID is required")
	}

	if cmd.CommandType == "" {
		return errors.New("command type is required")
	}

	if cmd.Status == "" {
		return errors.New("status is required")
	}

	validStatuses := []string{"pending", "running", "completed", "failed", "cancelled"}
	if !contains(validStatuses, cmd.Status) {
		return fmt.Errorf("invalid status: %s", cmd.Status)
	}

	if cmd.Source != "manual" && cmd.Source != "system" {
		return fmt.Errorf("source must be 'manual' or 'system', got: %s", cmd.Source)
	}

	// Validate command type format
	if err := v.validateCommandType(cmd.CommandType); err != nil {
		return err
	}

	return nil
}

// ValidateSubsystemAction validates subsystem-specific actions
func (v *Validator) ValidateSubsystemAction(subsystem string, action string) error {
	validActions := map[string][]string{
		"storage": {"trigger", "enable", "disable", "set_interval"},
		"system":  {"trigger", "enable", "disable", "set_interval"},
		"docker":  {"trigger", "enable", "disable", "set_interval"},
		"updates": {"trigger", "enable", "disable", "set_interval"},
	}

	actions, ok := validActions[subsystem]
	if !ok {
		return fmt.Errorf("unknown subsystem: %s", subsystem)
	}

	if !contains(actions, action) {
		return fmt.Errorf("invalid action '%s' for subsystem '%s'", action, subsystem)
	}

	return nil
}

// ValidateInterval ensures scanner intervals are within bounds
func (v *Validator) ValidateInterval(subsystem string, minutes int) error {
	if minutes < v.minScannerMinutes {
		return fmt.Errorf("interval %d minutes below minimum %d for subsystem %s",
			minutes, v.minScannerMinutes, subsystem)
	}

	if minutes > v.maxScannerMinutes {
		return fmt.Errorf("interval %d minutes above maximum %d for subsystem %s",
			minutes, v.maxScannerMinutes, subsystem)
	}

	return nil
}

func (v *Validator) validateCommandType(commandType string) error {
	validPrefixes := []string{"scan_", "install_", "update_", "enable_", "disable_", "reboot"}

	for _, prefix := range validPrefixes {
		if len(commandType) >= len(prefix) && commandType[:len(prefix)] == prefix {
			return nil
		}
	}

	return fmt.Errorf("invalid command type format: %s", commandType)
}

func contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}
