// File Path: monorepo/cloud/maplepress-backend/internal/interface/http/handler/gateway/hello_handler.go
package gateway

import (
	"encoding/json"
	"fmt"
	"html"
	"net/http"

	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config/constants"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httperror"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpresponse"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpvalidation"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/logger"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/validation"
)

// HelloHandler handles the hello endpoint for authenticated users
type HelloHandler struct {
	logger *zap.Logger
}

// ProvideHelloHandler creates a new HelloHandler
func ProvideHelloHandler(logger *zap.Logger) *HelloHandler {
	return &HelloHandler{
		logger: logger,
	}
}

// HelloRequest represents the request body for the hello endpoint
type HelloRequest struct {
	Name string `json:"name"`
}

// HelloResponse represents the response for the hello endpoint
type HelloResponse struct {
	Message string `json:"message"`
}

// Handle handles the HTTP request for the hello endpoint
// Security: CWE-20, CWE-79, CWE-117 - Comprehensive input validation and sanitization
func (h *HelloHandler) Handle(w http.ResponseWriter, r *http.Request) {
	// M-2: Enforce strict Content-Type validation
	// CWE-436: Validate Content-Type before parsing
	if err := httpvalidation.ValidateJSONContentTypeStrict(r); err != nil {
		h.logger.Warn("invalid content type", zap.String("content_type", r.Header.Get("Content-Type")))
		httperror.ProblemBadRequest(w, err.Error())
		return
	}

	// Parse request body
	var req HelloRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		h.logger.Warn("invalid request body", zap.Error(err))
		httperror.ProblemBadRequest(w, "invalid request body")
		return
	}

	// H-1: Comprehensive input validation
	// CWE-20: Improper Input Validation
	validator := validation.NewValidator()

	// Validate required
	if err := validator.ValidateRequired(req.Name, "name"); err != nil {
		httperror.ProblemBadRequest(w, err.Error())
		return
	}

	// Validate length (1-100 characters is reasonable for a name)
	if err := validator.ValidateLength(req.Name, "name", 1, 100); err != nil {
		httperror.ProblemBadRequest(w, err.Error())
		return
	}

	// Validate printable characters only
	if err := validator.ValidatePrintable(req.Name, "name"); err != nil {
		httperror.ProblemBadRequest(w, err.Error())
		return
	}

	// M-1: Validate no HTML tags (XSS prevention)
	// CWE-79: Cross-site Scripting
	if err := validator.ValidateNoHTML(req.Name, "name"); err != nil {
		httperror.ProblemBadRequest(w, err.Error())
		return
	}

	// Sanitize input
	req.Name = validator.SanitizeString(req.Name)

	// H-2: Fix log injection vulnerability
	// CWE-117: Improper Output Neutralization for Logs
	// Hash the name to prevent log injection and protect PII
	nameHash := logger.HashString(req.Name)

	// L-1: Extract user ID from context for correlation
	// Get authenticated user info from JWT context
	userID := "unknown"
	if uid := r.Context().Value(constants.SessionUserID); uid != nil {
		if userIDUint, ok := uid.(uint64); ok {
			userID = fmt.Sprintf("%d", userIDUint)
		}
	}

	h.logger.Info("hello endpoint accessed",
		zap.String("user_id", userID),
		zap.String("name_hash", nameHash))

	// M-1: HTML-escape the name to prevent XSS in any context
	// CWE-79: Cross-site Scripting
	safeName := html.EscapeString(req.Name)

	// Create response with sanitized output
	response := HelloResponse{
		Message: fmt.Sprintf("Hello, %s! Welcome to MaplePress Backend.", safeName),
	}

	// Write response
	httpresponse.OK(w, response)
}
