package user

import (
	"net/http"

	"go.uber.org/zap"

	userdto "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/dto/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/middleware"
	userservice "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/user"
	userusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/user"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httperror"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpresponse"
)

// GetHandler handles getting a user by ID
type GetHandler struct {
	service userservice.GetUserService
	logger  *zap.Logger
}

// ProvideGetHandler creates a new GetHandler
func ProvideGetHandler(service userservice.GetUserService, logger *zap.Logger) *GetHandler {
	return &GetHandler{
		service: service,
		logger:  logger,
	}
}

// Handle handles the HTTP request for getting a user
func (h *GetHandler) Handle(w http.ResponseWriter, r *http.Request) {
	// Extract tenant from context
	tenantID, err := middleware.GetTenantID(r.Context())
	if err != nil {
		httperror.ProblemUnauthorized(w, "Tenant context is required to access this resource.")
		return
	}

	// Get user ID from path parameter
	id := r.PathValue("id")
	if id == "" {
		httperror.ProblemBadRequest(w, "User ID is required in the request path.")
		return
	}

	// Call service
	input := &userusecase.GetUserInput{ID: id}
	output, err := h.service.GetUser(r.Context(), tenantID, input)
	if err != nil {
		h.logger.Error("failed to get user", zap.Error(err))
		httperror.ProblemNotFound(w, "The requested user could not be found.")
		return
	}

	// Map to response DTO
	response := userdto.GetResponse{
		ID:        output.ID,
		Email:     output.Email,
		Name:      output.Name,
		CreatedAt: output.CreatedAt,
		UpdatedAt: output.UpdatedAt,
	}

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