package org.egl_cepgl.pm.controller.admin;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.egl_cepgl.pm.dto.*;
import org.egl_cepgl.pm.model.*;
import org.egl_cepgl.pm.service.ApplicantService;
import org.egl_cepgl.pm.service.FileCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Api("api/admin/applicants")
@RestController
@RequestMapping("api/admin/applicants")
public class ApplicantController
{
    private ApplicantService service;

    @Autowired
    public ApplicantController(ApplicantService service) {
        this.service = service;
    }

    //@PreAuthorize("hasAuthority('ROLE_default-roles-egl_pm')")
    @PostMapping(value = "/add",consumes= MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="Add ..", notes="Cette méthode permet de..", response = Applicant.class)
    @ApiResponses(value= { @ApiResponse(code= 200, message = "créé/modifié"), @ApiResponse(code= 400, message = "Non valide") })
    public ResponseEntity<ApplicantDto> add(@RequestBody Applicant obj, @RequestParam(required = false) Long procurement_id)
    {
        return ResponseEntity.status(HttpStatus.OK).body(ApplicantDto.fromEntity(this.service.save(obj, procurement_id)));
    }

    @GetMapping(value = "/all",produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="List ..", notes="Cette méthode permet..", responseContainer = "List<Applicant>")
    @ApiResponses(value= { @ApiResponse(code= 200, message = "Une liste des ..") })
    public ResponseEntity<Map<String, Object>> findAll(
            @RequestParam(required = false) String search,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "5") int size,
            @RequestParam(required = false) Boolean dateRange,
            @RequestParam(required = false) Date bdate,
            @RequestParam(required = false) Date edate
    ){
        Page<Applicant> objs= service.findAll(search, page, size, dateRange, bdate, edate);
        Map<String, Object> response = new HashMap<>();
        response.put("applicants", objs.getContent().stream().map(ApplicantDto::fromEntity).collect(Collectors.toList()));
        response.put("currentPage", objs.getNumber());
        response.put("totalItems", objs.getTotalElements());
        response.put("totalPages", objs.getTotalPages());

        return new ResponseEntity<>(response, HttpStatus.OK);
    }

    @GetMapping(value = "/applicant_names/{procurement_id}",produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="List ..", notes="Cette méthode permet..", responseContainer = "List<Applicant>")
    @ApiResponses(value= { @ApiResponse(code= 200, message = "Une liste des ..") })
    public ResponseEntity<List<Map<String, Object>>> findAllApplicantNames(@Nullable @PathVariable("procurement_id") Long procurement_id)
    {
        return ResponseEntity.ok(service.findAllApplicantNames(procurement_id));
    }

    @GetMapping(value = "/one/{applicant_id}",produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="List ..", notes="Cette méthode permet..", responseContainer = "List<Applicant>")
    @ApiResponses(value= { @ApiResponse(code= 200, message = "Une liste des ..") })
    public ResponseEntity<Optional<ApplicantDto>> findApplicantById(@PathVariable("applicant_id") Long applicant_id)
    {
        return ResponseEntity.ok(service.findApplicantById(applicant_id));
    }

    @GetMapping(value = "/findByEmail/{email}",produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="List ..", notes="Cette méthode permet..", responseContainer = "Applicant")
    @ApiResponses(value= { @ApiResponse(code= 200, message = "Une liste des ..") })
    public ResponseEntity<Optional<ApplicantDto>> findApplicantById(@PathVariable("email") String email)
    {
        return ResponseEntity.ok(service.findApplicantByEmail(email));
    }

    @GetMapping(value = "/getFiles/{applicant_id}",produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="List ..", notes="Cette méthode permet..", responseContainer = "List<Applicant>")
    @ApiResponses(value= { @ApiResponse(code= 200, message = "Une liste des ..") })
    public ResponseEntity<List<FileDto>> findAllFilesByApplicantId(@PathVariable("applicant_id") Long applicant_id)
    {
        return ResponseEntity.ok(service.findAllFilesByApplicantId(applicant_id));
    }

    @PutMapping(value = "/update",consumes= MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="Update ..", notes="Cette méthode permet de..", response = Applicant.class)
    @ApiResponses(value= { @ApiResponse(code= 200, message = "créé/modifié")})
    public ResponseEntity<ApplicantDto> update(@RequestBody Applicant obj, @RequestParam(required = false) Long procurement_id)
    {
        return ResponseEntity.status(HttpStatus.OK)
                .body(ApplicantDto.fromEntity(this.service.update(obj, procurement_id)));
    }

    @DeleteMapping(value = "/delete/{id}")
    @ApiOperation(value = "Suppression d'un..", notes = "Cette méthode permet de supprimer..")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Supprimé")
    })
    ResponseEntity delete(@PathVariable("id") Long id) {
        service.delete(id);
        return ResponseEntity.ok().build();
    }

    @PostMapping(value="/validateEmail", consumes= MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Boolean> validateCode(@RequestBody ValidateEmail obj)
    {
        return ResponseEntity.ok(service.existsByCode(obj.getEmail()));
    }

    @PutMapping(value = "/changeStatus",consumes= MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value="Update ..", notes="Cette méthode permet de..", response = Applicant.class)
    @ApiResponses(value= { @ApiResponse(code= 200, message = "créé/modifié"), @ApiResponse(code= 400, message = "Non valide") })
    public ResponseEntity<Applicant> changeStatus(@RequestBody Applicant obj)
    {
        return ResponseEntity.ok(service.changeStatus(obj));
    }
}







