package at.procon.dip.domain.ted.search.integration;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

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.domain.ted.entity.TedNoticeProjection;
import at.procon.dip.domain.ted.service.TedStructuredSearchService;
import at.procon.dip.testsupport.AbstractTedStructuredSearchIntegrationTest;
import at.procon.ted.config.TedProcessorProperties;
import at.procon.ted.model.dto.DocumentDtos.SearchRequest;
import at.procon.ted.model.entity.ContractNature;
import at.procon.ted.model.entity.NoticeType;
import at.procon.ted.model.entity.ProcedureType;
import at.procon.ted.model.entity.ProcurementDocument;
import at.procon.ted.service.SearchService;
import at.procon.ted.service.VectorizationService;
import java.time.LocalDate;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;

class TedStructuredSearchParityIntegrationTest extends AbstractTedStructuredSearchIntegrationTest {

    @Autowired
    private TedStructuredSearchService newSearchService;

    @Test
    void structuredSearch_should_match_legacy_for_shared_filters() {
        var created = dataFactory.createDocumentWithPrimaryRepresentation(
                "Road maintenance services in Graz",
                "Procurement summary",
                "Road maintenance and winter service.",
                DocumentType.TED_NOTICE,
                DocumentFamily.PROCUREMENT,
                "en",
                RepresentationType.SEMANTIC_TEXT
        );

        tedNoticeProjectionRepository.save(TedNoticeProjection.builder()
                .document(created.document())
                .publicationId("200000-2026")
                .noticeId("notice-200000-2026")
                .noticeType(NoticeType.CONTRACT_NOTICE)
                .buyerName("City of Graz")
                .buyerCountryCode("AUT")
                .buyerCity("Graz")
                .projectTitle("Road maintenance services")
                .contractNature(ContractNature.SERVICES)
                .procedureType(ProcedureType.OPEN)
                .publicationDate(LocalDate.of(2026, 4, 12))
                .euFunded(false)
                .build());

        procurementDocumentRepository.save(ProcurementDocument.builder()
                .documentHash("legacy-200000-2026")
                .publicationId("200000-2026")
                .noticeId("notice-200000-2026")
                .noticeType(NoticeType.CONTRACT_NOTICE)
                .buyerName("City of Graz")
                .buyerCountryCode("AUT")
                .buyerCity("Graz")
                .projectTitle("Road maintenance services")
                .contractNature(ContractNature.SERVICES)
                .procedureType(ProcedureType.OPEN)
                .publicationDate(LocalDate.of(2026, 4, 12))
                .euFunded(false)
                .build());

        SearchRequest request = SearchRequest.builder()
                .countryCode("AUT")
                .noticeType(NoticeType.CONTRACT_NOTICE)
                .contractNature(ContractNature.SERVICES)
                .procedureType(ProcedureType.OPEN)
                .projectTitleContains("maintenance")
                .publicationDateFrom(LocalDate.of(2026, 4, 1))
                .publicationDateTo(LocalDate.of(2026, 4, 30))
                .page(0)
                .size(20)
                .sortBy("publicationDate")
                .sortDirection("desc")
                .build();

        TedProcessorProperties props = new TedProcessorProperties();
        SearchService legacySearchService = new SearchService(procurementDocumentRepository, mock(VectorizationService.class), props);

        var legacy = legacySearchService.search(request);
        var current = newSearchService.search(request);

        assertThat(current.getTotalElements()).isEqualTo(legacy.getTotalElements());
        assertThat(current.getDocuments()).extracting("publicationId")
                .containsExactlyElementsOf(legacy.getDocuments().stream().map(d -> d.getPublicationId()).toList());
    }
}
