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

import java.time.OffsetDateTime;
import java.util.List;
import java.util.Map;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.iqser.red.service.persistence.service.v1.api.shared.model.FileStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive;

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 StatusResource {

    String STATUS_REST_PATH = ExternalApi.BASE_PATH + "/status";
    String CHANGES_SINCE_PATH = "/changes";
    String BULK_REST_PATH = "/bulk";
    String ASSIGNEE_REST_PATH = "/set-assignee";

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

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

    String ASSIGNEE_ID_REQUEST_PARAM = "assigneeId";

    String DELETED_PATH = "/softdeleted";


    @ResponseBody
    @PostMapping(value = STATUS_REST_PATH + DOSSIER_ID_PATH_VARIABLE + CHANGES_SINCE_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "See if there are changes of files in a specific dossier dossiers since param", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success."), @ApiResponse(responseCode = "404", description = "Dossier does not exist.")})
    JSONPrimitive<Boolean> hasChangesSince(@PathVariable(DOSSIER_ID) String dossierId, @RequestBody JSONPrimitive<OffsetDateTime> since);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @PostMapping(value = STATUS_REST_PATH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets the status for all files of a list of dossiers.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    Map<String, List<FileStatus>> getDossierStatus(@RequestBody List<String> dossierIds);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @PostMapping(value = STATUS_REST_PATH + DELETED_PATH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets the status for all soft deleted files of a list of dossiers.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    Map<String, List<FileStatus>> getSoftDeletedFilesForDossiers(@RequestBody List<String> dossierIds);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @GetMapping(value = STATUS_REST_PATH + DOSSIER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets the status for all files in a dossier.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK")})
    List<FileStatus> getDossierStatus(@PathVariable(DOSSIER_ID) String dossierId);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @GetMapping(value = STATUS_REST_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets the status for a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
    FileStatus getFileStatus(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + ASSIGNEE_REST_PATH + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
    @Operation(summary = "Assigns a user to a a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully assigned new owner to dossier."), @ApiResponse(responseCode = "404", description = "Not found")})
    void setCurrentFileAssignee(@PathVariable(DOSSIER_ID) String dossierId,
                                @PathVariable(FILE_ID) String fileId,
                                @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/under-review" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
    @Operation(summary = "Sets the status UNDER_REVIEW for a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusUnderReview(@PathVariable(DOSSIER_ID) String dossierId,
                              @PathVariable(FILE_ID) String fileId,
                              @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/under-approval" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
    @Operation(summary = "Sets the status UNDER_APPROVAL for a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusUnderApproval(@PathVariable(DOSSIER_ID) String dossierId,
                                @PathVariable(FILE_ID) String fileId,
                                @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + FILE_ID_PATH_VARIABLE)
    @Operation(summary = "Sets the status APPROVED for a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusApproved(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/set-assignee" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Assign a a user for a list of files.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully assigned new owner to dossier."), @ApiResponse(responseCode = "404", description = "Not found")})
    void setAssigneeForList(@PathVariable(DOSSIER_ID) String dossierId,
                            @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId,
                            @RequestBody List<String> fileIds);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/under-review" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Sets the status UNDER_REVIEW for a list of files.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusUnderReviewForList(@PathVariable(DOSSIER_ID) String dossierId,
                                     @RequestBody List<String> fileIds,
                                     @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/under-approval" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Sets the status UNDER_APPROVAL for a list of files.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusUnderApprovalForList(@PathVariable(DOSSIER_ID) String dossierId,
                                       @RequestBody List<String> fileIds,
                                       @RequestParam(value = ASSIGNEE_ID_REQUEST_PARAM, required = false) String assigneeId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/approved" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Sets the status APPROVED for a list of files.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusApprovedForList(@PathVariable(DOSSIER_ID) String dossierId, @RequestBody List<String> fileIds);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = STATUS_REST_PATH + "/new" + DOSSIER_ID_PATH_VARIABLE + BULK_REST_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Sets the status NEW for a list of files.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "OK")})
    void setStatusNewForList(@PathVariable(DOSSIER_ID) String dossierId, @RequestBody List<String> fileIds);


    @ResponseStatus(value = HttpStatus.OK)
    @ResponseBody
    @GetMapping(value = STATUS_REST_PATH + DELETED_PATH + DOSSIER_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Gets the deleted status for a file.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "404", description = "Not found")})
    List<FileStatus> getSoftDeletedDossierStatus(@PathVariable(DOSSIER_ID) String dossierId);

}
