package de.avatic.lcc.controller.report;

import de.avatic.lcc.dto.generic.NodeDTO;
import de.avatic.lcc.dto.report.ReportDTO;
import de.avatic.lcc.service.report.ExcelReportingService;
import de.avatic.lcc.service.report.ReportingService;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * Rest Controller for managing reports functionality, including viewing, downloading,
 * and searching for suppliers related to reporting based on specific materials.
 */
@RestController
@RequestMapping("/api/reports")
public class ReportingController {

    //TODO: rollenbeschränkung

    private final ReportingService reportingService;
    private final ExcelReportingService excelReportingService;

    /**
     * Constructor for ReportingController.
     *
     * @param reportingService      Service used for generating reports.
     * @param excelReportingService Service used for generating Excel files for reports.
     */
    public ReportingController(ReportingService reportingService, ExcelReportingService excelReportingService) {
        this.reportingService = reportingService;
        this.excelReportingService = excelReportingService;
    }

    /**
     * Fetches a list of suppliers for reporting purposes, based on material ID.
     *
     * @param materialId The ID of the material for which suppliers need to be found.
     * @return A list of suppliers grouped by categories.
     */
    @GetMapping({"/search", "/search/"})
    public ResponseEntity<List<List<NodeDTO>>> findSupplierForReporting(@RequestParam(value = "material") Integer materialId) {
        return ResponseEntity.ok(reportingService.findSupplierForReporting(materialId));
    }

    /**
     * Fetches the report for the given material and source nodes.
     *
     * @param materialId The ID of the material for which the report will be generated.
     * @param nodeIds    A list of node IDs (sources) to include in the report.
     * @return The generated report details.
     */
    @GetMapping({"/view", "/view/"})
    public ResponseEntity<List<ReportDTO>> getReport(@RequestParam(value = "material") Integer materialId, @RequestParam(value = "sources", required = false) List<Integer> nodeIds, @RequestParam(value = "userSources", required = false) List<Integer> userNodeIds) {
        return ResponseEntity.ok(reportingService.getReport(materialId, nodeIds, userNodeIds));
    }

    /**
     * Downloads an Excel report for the given material and source nodes.
     *
     * @param materialId The ID of the material for which the report will be downloaded.
     * @param nodeIds    A list of node IDs (sources) to include in the downloaded report.
     * @return The Excel file as an attachment in the response.
     */
    @GetMapping({"/download", "/download/"})
    public ResponseEntity<InputStreamResource> downloadReport(@RequestParam(value = "material") Integer materialId, @RequestParam(value = "sources", required = false) List<Integer> nodeIds, @RequestParam(value = "userSources", required = false) List<Integer> userNodeIds) {

        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=lcc_report.xlsx");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(new InputStreamResource(excelReportingService.generateExcelReport(materialId, nodeIds, userNodeIds)));
    }
}
