package at.procon.dip.normalization.impl;

import at.procon.dip.domain.document.ContentRole;
import at.procon.dip.domain.document.DocumentType;
import at.procon.dip.domain.document.RepresentationType;
import at.procon.dip.extraction.spi.ExtractedStructuredPayload;
import at.procon.dip.ingestion.util.DocumentImportSupport;
import at.procon.dip.normalization.spi.RepresentationBuildRequest;
import at.procon.dip.normalization.spi.TextRepresentationBuilder;
import at.procon.dip.normalization.spi.TextRepresentationDraft;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Component
@Order(100)
public class DefaultGenericTextRepresentationBuilder implements TextRepresentationBuilder {

    public static final String BUILDER_KEY = "default-generic-text";

    @Override
    public boolean supports(DocumentType documentType) {
        return documentType != DocumentType.TED_NOTICE;
    }

    @Override
    public List<TextRepresentationDraft> build(RepresentationBuildRequest request) {
        String normalizedText = request.extractionResult().derivedTextByRole().get(ContentRole.NORMALIZED_TEXT);
        String htmlCleanText = request.extractionResult().derivedTextByRole().get(ContentRole.HTML_CLEAN);
        String baseText = StringUtils.hasText(normalizedText) ? normalizedText : htmlCleanText;
        if (!StringUtils.hasText(baseText)) {
            return List.of();
        }

        String title = findStructuredTitle(request).orElse(request.sourceDescriptor().fileName());
        String summary = DocumentImportSupport.ellipsize(baseText.replace('\n', ' ').trim(), 1200);
        String semantic = buildSemanticText(title, summary, request.detectionResult().documentType());

        List<TextRepresentationDraft> drafts = new ArrayList<>();
        /*
        drafts.add(new TextRepresentationDraft(
                RepresentationType.FULLTEXT,
                BUILDER_KEY,
                request.detectionResult().languageCode(),
                baseText,
                false,
                null,
                null,
                null,
                ContentRole.NORMALIZED_TEXT,
                Boolean.FALSE
        ));
         */
        drafts.add(new TextRepresentationDraft(
                RepresentationType.SEMANTIC_TEXT,
                BUILDER_KEY,
                request.detectionResult().languageCode(),
                semantic,
                true,
                null,
                null,
                null,
                ContentRole.NORMALIZED_TEXT,
                Boolean.TRUE
        ));
        /*
        if (StringUtils.hasText(title)) {
            drafts.add(new TextRepresentationDraft(
                    RepresentationType.TITLE_ABSTRACT,
                    BUILDER_KEY,
                    request.detectionResult().languageCode(),
                    title + "\n\n" + summary,
                    false,
                    null,
                    null,
                    null,
                    ContentRole.NORMALIZED_TEXT,
                    Boolean.FALSE
            ));
        }
        drafts.add(new TextRepresentationDraft(
                RepresentationType.SUMMARY,
                BUILDER_KEY,
                request.detectionResult().languageCode(),
                summary,
                false,
                null,
                null,
                null,
                ContentRole.NORMALIZED_TEXT,
                Boolean.FALSE
        ));
         */
        return drafts;
    }

    private Optional<String> findStructuredTitle(RepresentationBuildRequest request) {
        return request.extractionResult().structuredPayloads().stream()
                .map(ExtractedStructuredPayload::attributes)
                .filter(Objects::nonNull)
                .map(attributes -> attributes.get("title"))
                .filter(String.class::isInstance)
                .map(String.class::cast)
                .filter(StringUtils::hasText)
                .findFirst();
    }

    private String buildSemanticText(String title, String summary, DocumentType documentType) {
        StringBuilder sb = new StringBuilder();
        sb.append("Document type: ").append(documentType.name()).append('\n');
        if (StringUtils.hasText(title)) {
            sb.append("Title: ").append(title.trim()).append("\n\n");
        }
        sb.append(summary);
        return sb.toString().trim();
    }
}
