package at.procon.dip.embedding.service;

import at.procon.dip.domain.document.DocumentType;
import at.procon.dip.domain.document.EmbeddingStatus;
import at.procon.dip.domain.document.RepresentationType;
import at.procon.dip.domain.document.entity.DocumentTextRepresentation;
import at.procon.dip.domain.document.repository.DocumentTextRepresentationRepository;
import at.procon.dip.embedding.job.service.EmbeddingJobService;
import at.procon.dip.embedding.model.EmbeddingJobType;
import at.procon.dip.embedding.registry.EmbeddingModelRegistry;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

@Service
@RequiredArgsConstructor
public class ScopedEmbeddingEnqueueService {

    private static final int MAX_LIMIT = 10_000;

    private final DocumentTextRepresentationRepository representationRepository;
    private final EmbeddingJobService jobService;
    private final EmbeddingModelRegistry modelRegistry;

    @Transactional
    public ScopedEmbeddingEnqueueResult enqueueByDocumentType(DocumentType documentType,
                                                             RepresentationType representationType,
                                                             String builderKey,
                                                             boolean primaryOnly,
                                                             String modelKey,
                                                             boolean force,
                                                             int limit) {
        return enqueueByDocumentType(documentType, representationType, builderKey, primaryOnly, modelKey, force, 0, limit);
    }

    @Transactional
    public ScopedEmbeddingEnqueueResult enqueueByDocumentType(DocumentType documentType,
                                                             RepresentationType representationType,
                                                             String builderKey,
                                                             boolean primaryOnly,
                                                             String modelKey,
                                                             boolean force,
                                                             int pageNumber,
                                                             int limit) {
        String effectiveModelKey = StringUtils.hasText(modelKey)
                ? modelKey
                : modelRegistry.getRequiredDefaultDocumentModelKey();
        modelRegistry.getRequired(effectiveModelKey);

        int effectiveLimit = Math.max(1, Math.min(limit, MAX_LIMIT));
        int effectivePageNumber = Math.max(0, pageNumber);
        String normalizedBuilderKey = StringUtils.hasText(builderKey) ? builderKey.trim() : null;

        List<DocumentTextRepresentation> representations = representationRepository.findEmbeddingCandidatesByDocumentType(
                documentType,
                representationType,
                normalizedBuilderKey,
                primaryOnly,
                effectiveModelKey,
                EmbeddingStatus.COMPLETED,
                force,
                PageRequest.of(effectivePageNumber, effectiveLimit)
        );

        int jobs = 0;
        for (DocumentTextRepresentation representation : representations) {
            jobService.enqueueForRepresentation(
                    representation.getDocument().getId(),
                    representation.getId(),
                    effectiveModelKey,
                    EmbeddingJobType.DOCUMENT_EMBED
            );
            jobs++;
        }

        return new ScopedEmbeddingEnqueueResult(
                documentType,
                representationType,
                normalizedBuilderKey,
                primaryOnly,
                effectiveModelKey,
                force,
                effectiveLimit,
                representations.size(),
                jobs
        );
    }
}
