package page

import (
	"context"
	"fmt"

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

	domainpage "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/page"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/search"
)

// IndexPageToSearchUseCase indexes pages to the search engine
type IndexPageToSearchUseCase struct {
	searchClient *search.Client
	logger       *zap.Logger
}

// ProvideIndexPageToSearchUseCase creates a new IndexPageToSearchUseCase
func ProvideIndexPageToSearchUseCase(
	searchClient *search.Client,
	logger *zap.Logger,
) *IndexPageToSearchUseCase {
	return &IndexPageToSearchUseCase{
		searchClient: searchClient,
		logger:       logger,
	}
}

// Execute indexes a batch of pages to Meilisearch
func (uc *IndexPageToSearchUseCase) Execute(
	ctx context.Context,
	siteID gocql.UUID,
	pages []*domainpage.Page,
) (int, error) {
	if len(pages) == 0 {
		return 0, nil
	}

	// Convert pages to search documents
	documents := make([]search.PageDocument, 0, len(pages))
	for _, page := range pages {
		if page.ShouldIndex() {
			page.MarkIndexed()

			doc := search.PageDocument{
				ID:          page.PageID,
				SiteID:      page.SiteID.String(),
				TenantID:    page.TenantID.String(),
				Title:       page.Title,
				Content:     page.Content,
				Excerpt:     page.Excerpt,
				URL:         page.URL,
				Status:      page.Status,
				PostType:    page.PostType,
				Author:      page.Author,
				PublishedAt: page.PublishedAt.Unix(),
				ModifiedAt:  page.ModifiedAt.Unix(),
			}

			documents = append(documents, doc)
		}
	}

	if len(documents) == 0 {
		return 0, nil
	}

	// Bulk index to Meilisearch
	_, err := uc.searchClient.AddDocuments(siteID.String(), documents)
	if err != nil {
		uc.logger.Error("failed to index documents", zap.Error(err))
		return 0, fmt.Errorf("failed to index documents: %w", err)
	}

	return len(documents), nil
}
