package com.oguerreiro.resilient.web.rest;

import java.net.URISyntaxException;

import org.springframework.data.domain.Sort;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.oguerreiro.resilient.domain.OutputData;
import com.oguerreiro.resilient.repository.OutputDataRepository;
import com.oguerreiro.resilient.service.OutputDataService;
import com.oguerreiro.resilient.service.criteria.OutputDataCriteria;
import com.oguerreiro.resilient.service.dto.OutputDataDTO;
import com.oguerreiro.resilient.service.query.OutputDataQueryService;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;

/**
 * READONLY
 * REST controller for managing {@link com.oguerreiro.resilient.domain.OutputData}.
 */
@RestController
@RequestMapping("/api/output-data")
public class OutputDataResource
    extends AbstractResilientQueryResource<OutputData, OutputDataDTO, Long, OutputDataCriteria> {

  private static final String ENTITY_NAME = "outputData";
  private final OutputDataService outputDataService;

  public OutputDataResource(OutputDataRepository outputDataRepository, OutputDataService outputDataService,
      OutputDataQueryService outputDataQueryService) {
    super(OutputData.class, outputDataRepository, outputDataService, outputDataQueryService);
    this.outputDataService = outputDataService;
  }

  /* Abstract methods impl*/
  @Override
  protected String getEntityName() {
    return ENTITY_NAME;
  }

  @Override
  protected Sort getAllSort() {
    return Sort.by(Sort.Order.asc("variable.code"));
  }

  /* Override and Unsupport standard endpoints */
  /**
   * {@code POST  /output-data} : Create a new outputData.
   * UNSUPPORTED. CANT CREATE OUTPUT DATA FROM FRONTEND
   */
  @Override
  @PostMapping("")
  public ResponseEntity<OutputDataDTO> create(@Valid @RequestBody OutputDataDTO outputDataDTO)
      throws URISyntaxException {
    log.debug("REST request to save OutputData : {}", outputDataDTO);
    throw new UnsupportedOperationException();
  }

  /**
   * {@code PUT  /output-data/:id} : Updates an existing outputData.
   * UNSUPPORTED. CANT UPDATE OUTPUT DATA FROM FRONTEND
   */
  @Override
  @PutMapping("/{id}")
  public ResponseEntity<OutputDataDTO> update(@PathVariable(value = "id", required = false) final Long id,
      @Valid @RequestBody OutputDataDTO outputDataDTO) throws URISyntaxException {
    log.debug("REST request to update OutputData : {}, {}", id, outputDataDTO);
    throw new UnsupportedOperationException();
  }

  /**
   * {@code PATCH  /output-data/:id} : Partial updates given fields of an existing outputData, field will ignore if it
   * is null
   * UNSUPPORTED. CANT UPDATE OUTPUT DATA FROM FRONTEND
   */
  @Override
  @PatchMapping(value = "/{id}", consumes = { "application/json", "application/merge-patch+json" })
  public ResponseEntity<OutputDataDTO> partialUpdate(@PathVariable(value = "id", required = false) final Long id,
      @NotNull @RequestBody OutputDataDTO outputDataDTO) throws URISyntaxException {
    log.debug("REST request to partial update OutputData partially : {}, {}", id, outputDataDTO);
    throw new UnsupportedOperationException();
  }

  /**
   * {@code DELETE  /output-data/:id} : delete the "id" outputData.
   * UNSUPPORTED. CANT DELETE OUTPUT DATA FROM FRONTEND
   */
  @Override
  @DeleteMapping("/{id}")
  public ResponseEntity<Void> delete(@PathVariable("id") Long id) {
    log.debug("REST request to delete OutputData : {}", id);
    throw new UnsupportedOperationException();
  }

  @GetMapping("/export/{periodVersionId}")
  public ResponseEntity<byte[]> export(@PathVariable("periodVersionId") Long periodVersionId) {
    log.debug("REST request to export : {}");

    byte[] fileContent = this.outputDataService.export(periodVersionId);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    headers.setContentDisposition(ContentDisposition.attachment().filename("report.xlsx").build());

    return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
  }
}
