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.SearchMode;
import at.procon.dip.search.dto.SearchRepresentationSelectionMode;
import at.procon.dip.search.dto.SearchRequest;
import at.procon.dip.testsupport.AbstractSemanticSearchIntegrationTest;
import at.procon.dip.testsupport.SemanticSearchTestDataFactory;
import at.procon.dip.testsupport.config.SearchTestConfig;
import at.procon.dip.testsupport.config.SearchTestJacksonConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Set;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@AutoConfigureMockMvc
@Import(SearchTestConfig.class)
@ImportAutoConfiguration({
        JacksonAutoConfiguration.class,
        HttpMessageConvertersAutoConfiguration.class,
        WebMvcAutoConfiguration.class
})
class GenericSemanticSearchEndpointIntegrationTest extends AbstractSemanticSearchIntegrationTest {

    @Autowired
    private SemanticSearchTestDataFactory dataFactory;

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private ObjectMapper objectMapper;

    @Test
    void searchEndpoint_should_return_hits_for_semantic_request() throws Exception {
        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();

        mockMvc.perform(post("/search")
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                        .characterEncoding("UTF-8")
                        .content(objectMapper.writeValueAsString(request)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.hits[0].title").value("District heating modernization strategy"))
                .andExpect(jsonPath("$.enginesUsed").isArray());
    }

    @Test
    void debugEndpoint_should_show_semantic_engine_in_plan() throws Exception {
        var modelKey = "mock-search"; //"e5-default";
        dataFactory.createAndEmbedPrimaryRepresentation(
                "Heat network planning",
                "Municipal energy planning",
                "District heating optimization strategy for municipal energy systems.",
                DocumentType.TEXT,
                DocumentFamily.GENERIC,
                "en",
                RepresentationType.SEMANTIC_TEXT,
                modelKey
        );

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

        mockMvc.perform(post("/search/debug")
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                        .characterEncoding("UTF-8")
                        .content(objectMapper.writeValueAsString(request)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.plan.engines").isArray())
                .andExpect(jsonPath("$.fusedResponse.hits[0].title").value("Heat network planning"));
    }
}
