package validation

import (
	"fmt"
	"net/http"
	"strconv"
)

// ValidatePathUUID validates a UUID path parameter
// CWE-20: Improper Input Validation
func ValidatePathUUID(r *http.Request, paramName string) (string, error) {
	value := r.PathValue(paramName)
	if value == "" {
		return "", fmt.Errorf("%s is required", paramName)
	}

	validator := NewValidator()
	if err := validator.ValidateUUID(value, paramName); err != nil {
		return "", err
	}

	return value, nil
}

// ValidatePathSlug validates a slug path parameter
// CWE-20: Improper Input Validation
func ValidatePathSlug(r *http.Request, paramName string) (string, error) {
	value := r.PathValue(paramName)
	if value == "" {
		return "", fmt.Errorf("%s is required", paramName)
	}

	validator := NewValidator()
	if err := validator.ValidateSlug(value, paramName); err != nil {
		return "", err
	}

	return value, nil
}

// ValidatePathInt validates an integer path parameter
// CWE-20: Improper Input Validation
func ValidatePathInt(r *http.Request, paramName string) (int64, error) {
	valueStr := r.PathValue(paramName)
	if valueStr == "" {
		return 0, fmt.Errorf("%s is required", paramName)
	}

	value, err := strconv.ParseInt(valueStr, 10, 64)
	if err != nil {
		return 0, fmt.Errorf("%s must be a valid integer", paramName)
	}

	if value <= 0 {
		return 0, fmt.Errorf("%s must be greater than 0", paramName)
	}

	return value, nil
}

// ValidatePagination validates pagination query parameters
// Returns limit and offset with defaults and bounds checking
func ValidatePagination(r *http.Request, defaultLimit int) (limit int, offset int, err error) {
	limit = defaultLimit
	offset = 0

	// Validate limit
	if limitStr := r.URL.Query().Get("limit"); limitStr != "" {
		parsedLimit, err := strconv.Atoi(limitStr)
		if err != nil || parsedLimit <= 0 || parsedLimit > 100 {
			return 0, 0, fmt.Errorf("limit must be between 1 and 100")
		}
		limit = parsedLimit
	}

	// Validate offset
	if offsetStr := r.URL.Query().Get("offset"); offsetStr != "" {
		parsedOffset, err := strconv.Atoi(offsetStr)
		if err != nil || parsedOffset < 0 {
			return 0, 0, fmt.Errorf("offset must be >= 0")
		}
		offset = parsedOffset
	}

	return limit, offset, nil
}

// ValidateSortField validates sort field against whitelist
// CWE-89: SQL Injection prevention via whitelist
func ValidateSortField(r *http.Request, allowedFields []string) (string, error) {
	sortBy := r.URL.Query().Get("sort_by")
	if sortBy == "" {
		return "", nil // Optional field
	}

	for _, allowed := range allowedFields {
		if sortBy == allowed {
			return sortBy, nil
		}
	}

	return "", fmt.Errorf("invalid sort_by field (allowed: %v)", allowedFields)
}

// ValidateQueryEmail validates an email query parameter
// CWE-20: Improper Input Validation
func ValidateQueryEmail(r *http.Request, paramName string) (string, error) {
	email := r.URL.Query().Get(paramName)
	if email == "" {
		return "", fmt.Errorf("%s is required", paramName)
	}

	emailValidator := NewEmailValidator()
	normalizedEmail, err := emailValidator.ValidateAndNormalize(email, paramName)
	if err != nil {
		return "", err
	}

	return normalizedEmail, nil
}
