import { Controller, Get, HttpCode, Param, ParseUUIDPipe, Req, UseInterceptors } from "@nestjs/common";
import { SearchService } from "../../core/services/common/search.service";
import { PageInterceptor } from "../../core/interceptors/page.interceptor";
import { ApiExtraModels, ApiGatewayTimeoutResponse, ApiOperation, ApiResponse, ApiTags, getSchemaPath } from "@nestjs/swagger";
import { RequestDto } from "../../core/domain/dtos/request.dto";
import { EsHitDto, EsResponseDto, PageDto, PaperDto } from "../../core/domain";

/**
 * /papers/ route controller
 */
@Controller({
    version: '1',
    path: 'papers',
})
@ApiExtraModels(RequestDto, EsHitDto, EsResponseDto)
export class PapersController {
    constructor(private searchService: SearchService) {}

    /**
     * Request handler for: GET /papers/search
     * @param query 
     * @param response 
     * @returns a response with a set of matching papers
     */
    @ApiTags('Search')
    @ApiOperation({ 
        summary: 'Finds papers by context based on the query',
    })
    @ApiResponse({
        status: 200,
        description: 'Returns back a page with acquired papers',
        type: PageDto
    })
    @ApiGatewayTimeoutResponse({
        description: 'Elasticsearch request timed out'
    })
    @Get('search')
    @UseInterceptors(PageInterceptor)
    @HttpCode(200)
    getByContext(@Req() request: RequestDto): Promise<EsResponseDto> {
        return this.searchService.findByContext(request.es_query).then(
            (response) => {
                return response;
            },
            (error) => {
                throw error;
            }
        );
    }

    /**
     * Request handler for GET /papers/{uuid}
     * @param uuid 
     * @param response 
     * @returns a response with a requested object
     */
    @ApiTags('Search')
    @ApiOperation({ 
        summary: 'Finds paper by its UUID',
        tags: ['Search']
    })
    @ApiResponse({
        status: 200,
        description: 'Returns back a paper',
        type: PaperDto
    })
    @ApiGatewayTimeoutResponse({
        description: 'Elasticsearch request timed out'
    })
    @Get(':uuid')
    @HttpCode(200)
    getByID(@Param('uuid', ParseUUIDPipe) uuid: string): Promise<PaperDto> {
        return this.searchService.findByID(uuid).then(
            (response: EsResponseDto) => {
                return response.hits.hits[0]._source;
            },
            (error) => {
                throw error;
            }
        );
    }
}