package at.procon.dip.domain.document.service;

import at.procon.dip.domain.document.entity.DocumentContent;
import at.procon.dip.domain.document.entity.DocumentTextRepresentation;
import at.procon.dip.domain.document.repository.DocumentTextRepresentationRepository;
import at.procon.dip.search.service.DocumentLexicalIndexService;
import at.procon.dip.domain.document.service.command.AddDocumentTextRepresentationCommand;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
public class DocumentRepresentationService {

    private final DocumentService documentService;
    private final DocumentContentService contentService;
    private final DocumentTextRepresentationRepository representationRepository;
    private final DocumentLexicalIndexService lexicalIndexService;

    public DocumentTextRepresentation addRepresentation(AddDocumentTextRepresentationCommand command) {
        DocumentContent content = command.contentId() == null ? null : contentService.getRequired(command.contentId());
        DocumentTextRepresentation representation = DocumentTextRepresentation.builder()
                .document(documentService.getRequired(command.documentId()))
                .content(content)
                .representationType(command.representationType())
                .builderKey(command.builderKey())
                .languageCode(command.languageCode())
                .tokenCount(command.tokenCount())
                .chunkIndex(command.chunkIndex())
                .chunkStartOffset(command.chunkStartOffset())
                .chunkEndOffset(command.chunkEndOffset())
                .primaryRepresentation(command.primaryRepresentation())
                .textBody(command.textBody())
                .build();
        DocumentTextRepresentation saved = representationRepository.saveAndFlush(representation);
        if (!command.deferLexicalIndex()) {
            lexicalIndexService.indexRepresentation(saved.getId());
        }
        return saved;
    }

    @Transactional(readOnly = true)
    public DocumentTextRepresentation getRequired(UUID representationId) {
        return representationRepository.findById(representationId)
                .orElseThrow(() -> new IllegalArgumentException("Unknown representation id: " + representationId));
    }

    @Transactional(readOnly = true)
    public List<DocumentTextRepresentation> findByDocument(UUID documentId) {
        return representationRepository.findByDocument_Id(documentId);
    }
}
