package com.iqser.red.service.persistence.service.v2.api.external.resource;

import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v2.api.external.model.DossierList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import static com.iqser.red.service.persistence.service.v2.api.external.resource.DossierTemplateResource.*;

@ApiResponses(value = {@ApiResponse(responseCode = "429", description = "Too many requests.")})
public interface DossierResource {

    String DOSSIER_PATH = "/dossiers";
    String PATH = ExternalApiConstants.BASE_PATH + DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + DOSSIER_PATH;
    String DOSSIER_ID_PARAM = "dossierId";
    String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID_PARAM + "}";

    String INCLUDE_ACTIVE_PARAM = "includeActive";
    String INCLUDE_ARCHIVED_PARAM = "includeArchived";
    String INCLUDE_SOFT_DELETED_PARAM = "includeSoftDeleted";


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @GetMapping(value = PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets all existing dossiers for a specific dossier template.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    DossierList getDossiers(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
                            @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to include active dossiers: If `true` (default) the response contains dossiers that are active, i.e. the dossier is neither archived nor soft-deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
                            @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to include archived dossiers: If `true` the response contains dossiers that have been archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
                            @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to include soft-deleted dossiers: If `true` the response contains dossiers that have been soft-deleted, i.e. the dossiers can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @GetMapping(value = PATH + DOSSIER_ID_PATH_PARAM, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets an existing dossier.", description = "By default, the requested dossier will be returned only if it is active. This behavior can be changed by using and combining the respective toggle parameters.")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
    Dossier getDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
                       @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId,
                       @Parameter(name = INCLUDE_ACTIVE_PARAM, description = "A Toggle to return an active dossier: If `true` the dossiers will be returned if it is active, i.e. the dossiers is neither archived nor deleted.") @RequestParam(name = INCLUDE_ACTIVE_PARAM, defaultValue = "true", required = false) boolean includeActive,
                       @Parameter(name = INCLUDE_ARCHIVED_PARAM, description = "A Toggle to return an archived dossier: If `true` the dossier will be returned if it is archived.") @RequestParam(name = INCLUDE_ARCHIVED_PARAM, defaultValue = "false", required = false) boolean includeArchived,
                       @Parameter(name = INCLUDE_SOFT_DELETED_PARAM, description = "A Toggle to return a soft-deleted dossier: If `true` the dossier will be returned if it has been soft-deleted, i.e. the dossier can still be restored.") @RequestParam(name = INCLUDE_SOFT_DELETED_PARAM, defaultValue = "false", required = false) boolean includeSoftDeleted);


    @ResponseBody
    @PostMapping(value = PATH, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Creates or updates a dossier for a specific dossier template.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "201", description = "Successfully saved the dossier."), @ApiResponse(responseCode = "400", description = "Malformed request parameters or body"), @ApiResponse(responseCode = "409", description = "Duplicate")})
    ResponseEntity<Dossier> createDossierOrUpdateDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
                                                         @RequestBody DossierRequest dossier);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @DeleteMapping(value = PATH + DOSSIER_ID_PATH_PARAM)
    @Operation(summary = "Deletes an existing dossier.", description = "Dossiers get soft-deleted unless specified other. A soft-deleted dossier can be restored during a retention period that is configured in the application settings. The default retention period is 96h.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Successfully deleted the dossier."), @ApiResponse(responseCode = "404", description = "Not found")})
    void deleteDossier(@Parameter(name = DOSSIER_TEMPLATE_ID_PARAM, description = "The identifier of the dossier template that is used for the dossier.", required = true) @PathVariable(DOSSIER_TEMPLATE_ID_PARAM) String dossierTemplateId,
                       @Parameter(name = DOSSIER_ID_PARAM, description = "The identifier of the dossier to retrieve.", required = true) @PathVariable(DOSSIER_ID_PARAM) String dossierId);


}
