package at.procon.dip.extraction.impl;

import at.procon.dip.domain.document.ContentRole;
import at.procon.dip.domain.document.DocumentType;
import at.procon.dip.extraction.spi.ExtractedStructuredPayload;
import at.procon.dip.extraction.spi.DocumentExtractor;
import at.procon.dip.extraction.spi.ExtractionRequest;
import at.procon.dip.extraction.spi.ExtractionResult;
import at.procon.dip.ingestion.util.DocumentImportSupport;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
public class PlainTextDocumentExtractor implements DocumentExtractor {

    @Override
    public boolean supports(DocumentType documentType, String mimeType) {
        return documentType == DocumentType.TEXT
                || documentType == DocumentType.MARKDOWN
                || documentType == DocumentType.XML_GENERIC
                || (documentType == DocumentType.UNKNOWN && DocumentImportSupport.isLikelyTextMime(mimeType))
                || DocumentImportSupport.isLikelyTextMime(mimeType);
    }

    @Override
    public ExtractionResult extract(ExtractionRequest extractionRequest) {
        String text = extractionRequest.textContent();
        if (!StringUtils.hasText(text) && extractionRequest.binaryContent() != null) {
            text = new String(extractionRequest.binaryContent(), StandardCharsets.UTF_8);
        }
        text = normalizeText(text);

        if (!StringUtils.hasText(text)) {
            return new ExtractionResult(Map.of(), List.of(), List.of("No text content extracted"));
        }

        String title = deriveTitle(text, extractionRequest.sourceDescriptor().fileName());
        return new ExtractionResult(
                Map.of(ContentRole.NORMALIZED_TEXT, text),
                List.of(new ExtractedStructuredPayload("generic-document", Map.of("title", title))),
                List.of()
        );
    }

    private String normalizeText(String text) {
        if (text == null) {
            return null;
        }
        return text.replace("\r\n", "\n")
                .replace('\r', '\n')
                .replaceAll("\\n{3,}", "\n\n")
                .replaceAll("[ \t]+\n", "\n")
                .trim();
    }

    private String deriveTitle(String text, String fallback) {
        if (StringUtils.hasText(text)) {
            for (String line : text.split("\\n")) {
                if (StringUtils.hasText(line)) {
                    return DocumentImportSupport.ellipsize(line.trim(), 240);
                }
            }
        }
        return fallback;
    }
}
