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

import java.util.List;

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.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.multipart.MultipartFile;

import com.iqser.red.service.persistence.service.v1.api.shared.model.DossierTemplateModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.DownloadResponse;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.CloneDossierTemplateRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.DossierTemplateStats;

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

@ResponseStatus(HttpStatus.OK)
public interface DossierTemplateResource {

    String DOSSIER_TEMPLATE_PATH = ExternalApi.BASE_PATH + "/dossier-template";
    String DOSSIER_TEMPLATE_ID = "dossierTemplateId";
    String DOSSIER_TEMPLATE_ID_PATH_VARIABLE = "/{" + DOSSIER_TEMPLATE_ID + "}";
    String CLONE_PATH = "/clone";
    String STATS_PATH = "/stats";
    String IMPORT_PATH = "/import";
    String EXPORT_PATH = "/prepare-export";


    @ResponseStatus(HttpStatus.ACCEPTED)
    @PostMapping(value = DOSSIER_TEMPLATE_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Creates a new DossierTemplates or updates an existing one.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "202", description = "Successfully created DossierTemplates."), @ApiResponse(responseCode = "400", description = "The create/update request is not valid."), @ApiResponse(responseCode = "409", description = "The create/update request is not valid.")})
    DossierTemplateModel createOrUpdateDossierTemplate(@RequestBody DossierTemplateModel dossierTemplate);


    @GetMapping(value = DOSSIER_TEMPLATE_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Lists all existing DossierTemplates.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "List of all existing DossierTemplates.")})
    List<DossierTemplateModel> getAllDossierTemplates();


    @GetMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Get a specific DossierTemplate by its ID", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "The DossierTemplate."), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
    DossierTemplateModel getDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @DeleteMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE)
    @Operation(summary = "Delete a specific DossierTemplate by its ID", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "The DossierTemplate was deleted"), @ApiResponse(responseCode = "404", description = "The DossierTemplate is not found.")})
    void deleteDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = DOSSIER_TEMPLATE_PATH + "/delete")
    @Operation(summary = "Delete multiple DossierTemplates by their IDs", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "The DossierTemplates were deleted"), @ApiResponse(responseCode = "404", description = "DossierTemplates not found.")})
    void deleteDossierTemplates(@RequestBody List<String> dossierTemplateIds);


    @PostMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + CLONE_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Clones a dossier template.", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Successfully cloned dossier templates."), @ApiResponse(responseCode = "400", description = "The clone request is not valid."), @ApiResponse(responseCode = "409", description = "The clone request is not valid.")})
    DossierTemplateModel cloneDossierTemplate(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId, @RequestBody CloneDossierTemplateRequest cloneDossierTemplateRequest);


    @Operation(summary = "Get Stats for a specific DossierTemplate", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200"), @ApiResponse(responseCode = "404", description = "Dossier template not found")})
    @GetMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + STATS_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    DossierTemplateStats getDossierTemplateStats(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId);


    @Operation(summary = "Get Stats for all DossierTemplates", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200")})
    @GetMapping(value = DOSSIER_TEMPLATE_PATH + STATS_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    List<DossierTemplateStats> getDossierTemplateStats();


    @Operation(summary = "Prepares an export download for given dossier template", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Success."), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier template not found.")})
    @GetMapping(value = DOSSIER_TEMPLATE_PATH + DOSSIER_TEMPLATE_ID_PATH_VARIABLE + EXPORT_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
    DownloadResponse prepareExportDownload(@PathVariable(DOSSIER_TEMPLATE_ID) String dossierTemplateId);


    @ResponseStatus(value = HttpStatus.NO_CONTENT)
    @PostMapping(value = DOSSIER_TEMPLATE_PATH + IMPORT_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @Operation(summary = "Receives an archive to import", description = "None")
    @ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Archive have successfully imported"), @ApiResponse(responseCode = "400", description = "Validation failed during import"), @ApiResponse(responseCode = "404", description = "The dossier template to update does not exist")})
    DossierTemplateModel importDossierTemplate(@RequestPart(name = "file") MultipartFile file,
                                               @RequestParam(value = DOSSIER_TEMPLATE_ID, required = false) String dossierTemplateId,
                                               @RequestParam(value = "updateExistingDossierTemplate", required = false, defaultValue = "false") boolean updateExistingDossierTemplate);

}
