package com.oguerreiro.resilient.web.rest;

import java.util.List;
import java.util.Map;
import java.util.Optional;

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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.oguerreiro.resilient.domain.DashboardComponent;
import com.oguerreiro.resilient.domain.DashboardComponentDetailValue;
import com.oguerreiro.resilient.domain.enumeration.DashboardComponentView;
import com.oguerreiro.resilient.repository.DashboardComponentRepository;
import com.oguerreiro.resilient.service.DashboardComponentService;
import com.oguerreiro.resilient.service.dto.DashboardComponentDTO;
import com.oguerreiro.resilient.service.dto.DashboardComponentDetailValueDTO;
import com.oguerreiro.resilient.service.mapper.DashboardComponentDetailValueMapper;

/**
 * REST controller for managing {@link com.oguerreiro.resilient.domain.UnitType}.
 */
@RestController
@RequestMapping("/api/dashboard-components")
public class DashboardComponentResource
    extends AbstractResilientResource<DashboardComponent, DashboardComponentDTO, Long> {

  private static final String ENTITY_NAME = "dashboardComponent";
  private final DashboardComponentDetailValueMapper dashboardComponentDetailValueMapper;
  private final DashboardComponentService dashboardComponentService;

  public DashboardComponentResource(DashboardComponentRepository dashboardComponentRepository,
      DashboardComponentService dashboardComponentService,
      DashboardComponentDetailValueMapper dashboardComponentDetailValueMapper) {
    super(DashboardComponent.class, dashboardComponentRepository, dashboardComponentService);
    this.dashboardComponentDetailValueMapper = dashboardComponentDetailValueMapper;
    this.dashboardComponentService = dashboardComponentService;
  }

  private DashboardComponentService getDashboardComponentService() {
    return (DashboardComponentService) super.getService();
  }

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

  /* DashboardComponentResource endpoints */
  /**
   * {@code GET /<entity path>/build/{id}} : builds a component filled with Output calculated values, ready to show
   *
   * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of entities in body.
   */
  @GetMapping("/build/{dashboardComponentId}/{periodVersionId}")
  public Map<String, List<DashboardComponentDetailValueDTO>> buildComponent(
      @PathVariable("dashboardComponentId") Long dashboardComponentId,
      @PathVariable("periodVersionId") Long periodVersionId) {
    log.debug("REST request to get DashboardComponentView's.");

    Optional<DashboardComponentDTO> dashboardComponentDTO = getDashboardComponentService().findOne(
        dashboardComponentId);
    Map<String, List<DashboardComponentDetailValue>> values = getDashboardComponentService().buildDashboardComponentView(
        null, dashboardComponentId, periodVersionId);

    return this.dashboardComponentDetailValueMapper.mapToDto(values);
  }

  @GetMapping("/build/{organizationId}/{dashboardComponentId}/{periodVersionId}")
  public Map<String, List<DashboardComponentDetailValueDTO>> buildOrganizationComponent(
      @PathVariable("organizationId") Long organizationId,
      @PathVariable("dashboardComponentId") Long dashboardComponentId,
      @PathVariable("periodVersionId") Long periodVersionId) {
    log.debug("REST request to get DashboardComponentView's.");

    Optional<DashboardComponentDTO> dashboardComponentDTO = getDashboardComponentService().findOne(
        dashboardComponentId);
    Map<String, List<DashboardComponentDetailValue>> values = getDashboardComponentService().buildDashboardComponentView(
        organizationId, dashboardComponentId, periodVersionId);

    return this.dashboardComponentDetailValueMapper.mapToDto(values);
  }

  @GetMapping("/active")
  public List<DashboardComponentDTO> getAllActive() {
    log.debug("REST request to get all DashboardComponent's.");
    return getDashboardComponentService().findAllActive();
  }

  @GetMapping("/active/{view}")
  public List<DashboardComponentDTO> getAllActiveForView(@PathVariable("view") String dashboardComponentViewString) {
    log.debug("REST request to getAllActiveForView.");

    DashboardComponentView dashboardComponentView = DashboardComponentView.valueOf(dashboardComponentViewString);
    return getDashboardComponentService().findAllActiveForView(dashboardComponentView);
  }

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

    byte[] fileContent = this.dashboardComponentService.export(organizationId, dashboardComponentId, 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);
  }
}
