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

import java.util.List;
import java.util.Set;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.iqser.red.service.persistence.service.v1.api.shared.model.CommentResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comments;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualAddResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddCommentRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ForceRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.LegalBasisChangeRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RecategorizationRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.RemoveRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ResizeRedactionRequestModel;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;

public interface ManualRedactionResource {

    String MANUAL_REDACTION_REST_PATH = ExternalApi.BASE_PATH + "/manualRedaction";

    String DOSSIER_ID = "dossierId";
    String DOSSIER_ID_PATH_PARAM = "/{" + DOSSIER_ID + "}";

    String FILE_ID = "fileId";
    String FILE_ID_PATH_VARIABLE = "/{" + FILE_ID + "}";

    String ANNOTATION_ID = "annotationId";
    String ANNOTATION_ID_PATH_VARIABLE = "/{" + ANNOTATION_ID + "}";

    String COMMENT_ID = "commentId";
    String COMMENT_ID_PATH_VARIABLE = "/{" + COMMENT_ID + "}";


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @DeleteMapping(MANUAL_REDACTION_REST_PATH + "/bulk/undo" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE)
    @Operation(summary = "Undo a list of manual requests or redactions", description = "Can only be done be the " + "user who added the request/redaction.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void undo(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set<String> annotationIds);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/comment/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Adds a comment to a redaction/redaction request", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    CommentResponse addComment(@PathVariable(DOSSIER_ID) String dossierId,
                               @PathVariable(FILE_ID) String fileId,
                               @PathVariable(ANNOTATION_ID) String annotationId,
                               @RequestBody AddCommentRequestModel addCommentRequest);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @DeleteMapping(value = MANUAL_REDACTION_REST_PATH + "/comment/undo" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE + ANNOTATION_ID_PATH_VARIABLE + COMMENT_ID_PATH_VARIABLE)
    @Operation(summary = "Undo a comment", description = "Can only be done be the user who added" + " the comment.")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void undoComment(@PathVariable(DOSSIER_ID) String dossierId,
                     @PathVariable(FILE_ID) String fileId,
                     @PathVariable(ANNOTATION_ID) String annotationId,
                     @PathVariable(COMMENT_ID) String commentId);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/add" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Adds a manual redaction", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> addRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                             @PathVariable(FILE_ID) String fileId,
                                             @RequestBody Set<AddRedactionRequestModel> addRedactionRequest);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/remove" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Removes the redactions list", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> removeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                                @PathVariable(FILE_ID) String fileId,
                                                @RequestBody Set<RemoveRedactionRequestModel> removeRedactionRequests);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/force" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Forces the redactions list", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> forceRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                               @PathVariable(FILE_ID) String fileId,
                                               @RequestBody Set<ForceRedactionRequestModel> forceRedactionRequests);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/legalBasisChange" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Changes the legal basis reasons list", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> legalBasisChangeBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                                 @PathVariable(FILE_ID) String fileId,
                                                 @RequestBody Set<LegalBasisChangeRequestModel> legalBasisChangeRequests);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/recategorize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Recategorizes the list of redaction log entries", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> recategorizeBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                             @PathVariable(FILE_ID) String fileId,
                                             @RequestBody Set<RecategorizationRequestModel> recategorizationRequests);


    @ResponseStatus(value = HttpStatus.OK)
    @PostMapping(value = MANUAL_REDACTION_REST_PATH + "/bulk/redaction/resize" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Resizes the redactions list", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<ManualAddResponse> resizeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId,
                                                @PathVariable(FILE_ID) String fileId,
                                                @RequestBody Set<ResizeRedactionRequestModel> resizeRedactionRequests);


    @ResponseStatus(value = HttpStatus.OK)
    @GetMapping(value = MANUAL_REDACTION_REST_PATH + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Returns the manual redactions", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    ManualRedactions getManualRedactions(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);


    @ResponseStatus(value = HttpStatus.OK)
    @GetMapping(value = MANUAL_REDACTION_REST_PATH + "/comments" + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Returns the comments for a specific file", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    Comments getComments(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);

}
