package at.procon.dip.search.integration;

import at.procon.dip.domain.document.DocumentFamily;
import at.procon.dip.domain.document.DocumentType;
import at.procon.dip.domain.document.RepresentationType;
import at.procon.dip.search.dto.SearchEngineType;
import at.procon.dip.search.dto.SearchMode;
import at.procon.dip.search.dto.SearchRepresentationSelectionMode;
import at.procon.dip.search.dto.SearchRequest;
import at.procon.dip.search.dto.SearchResponse;
import at.procon.dip.search.service.SearchOrchestrator;
import at.procon.dip.search.spi.SearchDocumentScope;
import at.procon.dip.testsupport.AbstractSemanticSearchIntegrationTest;
import at.procon.dip.testsupport.SemanticSearchTestDataFactory;
import java.util.Set;

import at.procon.dip.testsupport.config.SearchTestConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;

import static org.assertj.core.api.Assertions.assertThat;

@Import(SearchTestConfig.class)
class GenericSemanticSearchOrchestratorIntegrationTest extends AbstractSemanticSearchIntegrationTest {

    @Autowired
    private SemanticSearchTestDataFactory dataFactory;

    @Autowired
    private SearchOrchestrator searchOrchestrator;

    @Test
    void semanticMode_should_return_embedded_document() {
        dataFactory.createAndEmbedPrimaryRepresentation(
                "District heating modernization strategy",
                "Municipal energy planning",
                "District heating optimization strategy for municipal energy systems.",
                DocumentType.TEXT,
                DocumentFamily.GENERIC,
                "en",
                RepresentationType.SEMANTIC_TEXT,
                "mock-search"
        );

        SearchRequest request = SearchRequest.builder()
                .queryText("district heating optimization")
                .modes(Set.of(SearchMode.SEMANTIC))
                .representationSelectionMode(SearchRepresentationSelectionMode.PRIMARY_ONLY)
                .semanticModelKey("mock-search")
                .build();

        SearchResponse response = searchOrchestrator.search(
                request,
                new SearchDocumentScope(Set.of(), Set.of(DocumentType.TEXT), Set.of(DocumentFamily.GENERIC), null, null, null)
        );

        assertThat(response.getHits()).isNotEmpty();
        assertThat(response.getHits().getFirst().getTitle()).isEqualTo("District heating modernization strategy");
        assertThat(response.getEnginesUsed()).contains(SearchEngineType.PGVECTOR_SEMANTIC);
        assertThat(response.getHits().getFirst().getPrimaryEngine()).isEqualTo(SearchEngineType.PGVECTOR_SEMANTIC);
    }

    @Test
    void hybridMode_should_include_semantic_engine_alongside_lexical_engines() {
        dataFactory.createAndEmbedPrimaryRepresentation(
                "Energy transition framework",
                "Framework for district heating rollout",
                "District heating optimization framework for urban energy transition.",
                DocumentType.TEXT,
                DocumentFamily.GENERIC,
                "en",
                RepresentationType.SEMANTIC_TEXT,
                "mock-search"
        );

        SearchRequest request = SearchRequest.builder()
                .queryText("district heating optimization")
                .modes(Set.of(SearchMode.HYBRID))
                .representationSelectionMode(SearchRepresentationSelectionMode.PRIMARY_ONLY)
                .semanticModelKey("mock-search")
                .build();

        SearchResponse response = searchOrchestrator.search(
                request,
                new SearchDocumentScope(Set.of(), Set.of(DocumentType.TEXT), Set.of(DocumentFamily.GENERIC), null, null, null)
        );

        assertThat(response.getHits()).isNotEmpty();
        assertThat(response.getEnginesUsed()).contains(SearchEngineType.POSTGRES_FULLTEXT, SearchEngineType.PGVECTOR_SEMANTIC);
        assertThat(response.getHits().getFirst().getFinalScore()).isGreaterThan(0.0d);
    }
}
