package at.procon.dip.domain.ted.web;

import at.procon.dip.runtime.condition.ConditionalOnRuntimeMode;
import at.procon.dip.runtime.config.RuntimeMode;
import at.procon.dip.domain.ted.service.TedStructuredSearchService;
import at.procon.ted.model.dto.DocumentDtos.SearchRequest;
import at.procon.ted.model.dto.DocumentDtos.SearchResponse;
import at.procon.ted.model.entity.ContractNature;
import at.procon.ted.model.entity.NoticeType;
import at.procon.ted.model.entity.ProcedureType;
import io.swagger.v3.oas.annotations.Parameter;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/v1/documents")
@RequiredArgsConstructor
@ConditionalOnRuntimeMode(RuntimeMode.NEW)
public class TedStructuredSearchController {

    private final TedStructuredSearchService searchService;

    @GetMapping("/search")
    public ResponseEntity<SearchResponse> searchDocuments(
            @RequestParam(required = false) String countryCode,
            @RequestParam(required = false) List<String> countryCodes,
            @RequestParam(required = false) NoticeType noticeType,
            @RequestParam(required = false) ContractNature contractNature,
            @RequestParam(required = false) ProcedureType procedureType,
            @RequestParam(required = false) String cpvPrefix,
            @RequestParam(required = false) List<String> cpvCodes,
            @RequestParam(required = false) String nutsCode,
            @RequestParam(required = false) List<String> nutsCodes,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate publicationDateFrom,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate publicationDateTo,
            @RequestParam(required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) OffsetDateTime submissionDeadlineAfter,
            @RequestParam(required = false) Boolean euFunded,
            @RequestParam(required = false) String buyerNameContains,
            @RequestParam(required = false) String projectTitleContains,
            @RequestParam(required = false, name = "q") String q,
            @RequestParam(required = false) Double similarityThreshold,
            @RequestParam(required = false) Boolean includeFacets,
            @RequestParam(required = false) Integer facetBucketLimit,
            @RequestParam(required = false, defaultValue = "0") Integer page,
            @RequestParam(required = false, defaultValue = "20") Integer size,
            @RequestParam(required = false, defaultValue = "publicationDate") String sortBy,
            @RequestParam(required = false, defaultValue = "desc") String sortDirection
    ) {
        SearchRequest request = SearchRequest.builder()
                .countryCode(countryCode)
                .countryCodes(countryCodes)
                .noticeType(noticeType)
                .contractNature(contractNature)
                .procedureType(procedureType)
                .cpvPrefix(cpvPrefix)
                .cpvCodes(cpvCodes)
                .nutsCode(nutsCode)
                .nutsCodes(nutsCodes)
                .publicationDateFrom(publicationDateFrom)
                .publicationDateTo(publicationDateTo)
                .submissionDeadlineAfter(submissionDeadlineAfter)
                .euFunded(euFunded)
                .buyerNameContains(buyerNameContains)
                .projectTitleContains(projectTitleContains)
                .semanticQuery(q)
                .similarityThreshold(similarityThreshold)
                .includeFacets(includeFacets)
                .facetBucketLimit(facetBucketLimit)
                .page(page)
                .size(size)
                .sortBy(sortBy)
                .sortDirection(sortDirection)
                .build();
        return ResponseEntity.ok(searchService.search(request));
    }

    @PostMapping("/search")
    public ResponseEntity<SearchResponse> searchDocumentsPost(@RequestBody SearchRequest request) {
        return ResponseEntity.ok(searchService.search(request));
    }
}
