package site

import (
	"net/http"

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

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config/constants"
	sitedto "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/interface/http/dto/site"
	siteservice "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/service/site"
	siteusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/site"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httperror"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/httpresponse"
)

// ListHandler handles listing sites for a tenant
type ListHandler struct {
	service siteservice.ListSitesService
	logger  *zap.Logger
}

// ProvideListHandler creates a new ListHandler
func ProvideListHandler(service siteservice.ListSitesService, logger *zap.Logger) *ListHandler {
	return &ListHandler{
		service: service,
		logger:  logger,
	}
}

// Handle handles the HTTP request for listing sites
// Requires JWT authentication and tenant context
func (h *ListHandler) Handle(w http.ResponseWriter, r *http.Request) {
	// Get tenant ID from context
	tenantIDStr, ok := r.Context().Value(constants.ContextKeyTenantID).(string)
	if !ok {
		h.logger.Error("tenant ID not found in context")
		httperror.ProblemUnauthorized(w, "Tenant context is required to access this resource.")
		return
	}

	tenantID, err := gocql.ParseUUID(tenantIDStr)
	if err != nil {
		h.logger.Error("invalid tenant ID format", zap.Error(err))
		httperror.ProblemBadRequest(w, "Invalid tenant ID format. Please ensure you have a valid session.")
		return
	}

	// Call service
	input := &siteusecase.ListSitesInput{}
	output, err := h.service.ListSites(r.Context(), tenantID, input)
	if err != nil {
		h.logger.Error("failed to list sites",
			zap.Error(err),
			zap.String("tenant_id", tenantID.String()))
		httperror.ProblemInternalServerError(w, "Failed to retrieve your sites. Please try again later.")
		return
	}

	// Map to response DTO
	items := make([]sitedto.SiteListItem, len(output.Sites))
	for i, s := range output.Sites {
		items[i] = sitedto.SiteListItem{
			ID:                s.ID.String(),
			Domain:            s.Domain,
			Status:            s.Status,
			IsVerified:        s.IsVerified,
			TotalPagesIndexed: s.TotalPagesIndexed,
			CreatedAt:         s.CreatedAt,
		}
	}

	response := sitedto.ListResponse{
		Sites: items,
		Total: len(items),
	}

	// Write response with pretty JSON
	httpresponse.OK(w, response)
}
