package org.fuseri.moduleexercise.answer;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.fuseri.model.dto.exercise.AnswerCreateDto;
import org.fuseri.model.dto.exercise.AnswerDto;
import org.fuseri.moduleexercise.ModuleExerciseApplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;

/**
 * Represent a REST API controller for answers
 * Handle HTTP requests related to answers
 */
@RestController
@RequestMapping("/answers")
public class AnswerController {

    private final AnswerFacade facade;

    @Autowired
    public AnswerController(AnswerFacade facade) {
        this.facade = facade;
    }

    /**
     * Create a new answer for the given question ID
     *
     * @param dto the AnswerCreateDto object containing information about the answer to create
     * @return a ResponseEntity containing an AnswerDto object representing the newly created answer, or a 404 Not Found response
     * if the question with the specified ID in dto was not found
     */
    @Operation(security = @SecurityRequirement(name = ModuleExerciseApplication.SECURITY_SCHEME_NAME),
            summary = "Create new answer for question", description = "Creates new answer for question.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "201", description = "Answers created successfully."),
            @ApiResponse(responseCode = "400", description = "Invalid input.")
    })
    @PostMapping
    public ResponseEntity<AnswerDto> create(@Valid @RequestBody AnswerCreateDto dto) {
        return ResponseEntity.status(HttpStatus.CREATED).body(facade.create(dto));
    }

    /**
     * Update an answer
     *
     * @param id  of answer to update
     * @param dto dto with updated answer information
     * @return A ResponseEntity with an AnswerDto object representing the updated answer on an HTTP status code of 200 if the update was successful.
     * or a NOT_FOUND response if the answer ID is invalid
     */
    @Operation(security = @SecurityRequirement(name = ModuleExerciseApplication.SECURITY_SCHEME_NAME),
            summary = "Update an answer", description = "Updates an answer with the specified ID.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "Answer with the specified ID updated successfully."),
            @ApiResponse(responseCode = "400", description = "Invalid input."),
            @ApiResponse(responseCode = "404", description = "Answer with the specified ID was not found.")
    })
    @PutMapping("/{id}")
    public ResponseEntity<AnswerDto> update(@NotNull @PathVariable long id, @Valid @RequestBody AnswerCreateDto dto) {
        return ResponseEntity.ok(facade.update(id, dto));
    }

    /**
     * Delete answer with the specified ID
     *
     * @param id of answer to delete
     * @throws ResponseStatusException if answer with specified id does not exist
     */
    @Operation(security = @SecurityRequirement(name = ModuleExerciseApplication.SECURITY_SCHEME_NAME),
            summary = "Delete an answer with specified ID", description = "Deletes an answer with the specified ID.")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "204", description = "Answer with the specified ID deleted successfully."),
            @ApiResponse(responseCode = "404", description = "Answer with the specified ID was not found.")
    })
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@NotNull @PathVariable long id) {
        facade.delete(id);
        return ResponseEntity.noContent().build();
    }
}
