// Package inviteemail provides HTTP handlers for invitation email endpoints
package inviteemail

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

	"github.com/gocql/gocql"
	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config/constants"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/interface/http/middleware"
	svc_inviteemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/inviteemail"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)

// SendInviteEmailHTTPHandler handles POST /api/v1/invites/send-email requests
type SendInviteEmailHTTPHandler struct {
	config     *config.Config
	logger     *zap.Logger
	service    svc_inviteemail.SendInviteEmailService
	middleware middleware.Middleware
}

// NewSendInviteEmailHTTPHandler creates a new handler for sending invitation emails
func NewSendInviteEmailHTTPHandler(
	cfg *config.Config,
	logger *zap.Logger,
	service svc_inviteemail.SendInviteEmailService,
	mw middleware.Middleware,
) *SendInviteEmailHTTPHandler {
	logger = logger.Named("SendInviteEmailHTTPHandler")
	return &SendInviteEmailHTTPHandler{
		config:     cfg,
		logger:     logger,
		service:    service,
		middleware: mw,
	}
}

// Pattern returns the URL pattern for this handler
func (*SendInviteEmailHTTPHandler) Pattern() string {
	return "POST /api/v1/invites/send-email"
}

// ServeHTTP implements http.Handler
func (h *SendInviteEmailHTTPHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// Apply middleware (authentication required)
	h.middleware.Attach(h.Execute)(w, req)
}

// Execute handles the actual request processing
func (h *SendInviteEmailHTTPHandler) Execute(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

	// Get user ID from context (set by auth middleware)
	userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
	if !ok {
		h.logger.Error("User ID not found in context or invalid type")
		httperror.RespondWithError(w, r, httperror.NewForUnauthorizedWithSingleField("auth", "Authentication required"))
		return
	}

	// Decode request body
	var req svc_inviteemail.SendInviteEmailRequestDTO
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		h.logger.Warn("Failed to decode request body", zap.Error(err))
		httperror.RespondWithError(w, r, httperror.NewForBadRequestWithSingleField("body", "Invalid request body"))
		return
	}

	// Execute service
	response, err := h.service.Execute(ctx, userID, &req)
	if err != nil {
		httperror.RespondWithError(w, r, err)
		return
	}

	// Return response
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(response)
}
