package de.avatic.lcc.controller.bulk;


import de.avatic.lcc.dto.bulk.BulkFileType;
import de.avatic.lcc.dto.bulk.BulkProcessingType;
import de.avatic.lcc.dto.bulk.BulkStatus;
import de.avatic.lcc.service.bulk.BulkExportService;
import de.avatic.lcc.service.bulk.BulkFileProcessingService;
import de.avatic.lcc.service.bulk.TemplateExportService;
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.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * REST controller for handling bulk operations, including file uploads, template generation,
 * and export downloads. It provides a comprehensive set of endpoints to manage processing
 * operations for supported file types based on defined business requirements.
 */
@RestController
@RequestMapping("/api/bulk")
public class BulkOperationController {

    private final BulkFileProcessingService bulkProcessingService;
    private final TemplateExportService templateExportService;
    private final BulkExportService bulkExportService;

    public BulkOperationController(BulkFileProcessingService bulkProcessingService, TemplateExportService templateExportService, BulkExportService bulkExportService) {
        this.bulkProcessingService = bulkProcessingService;
        this.templateExportService = templateExportService;
        this.bulkExportService = bulkExportService;
    }

    /**
     * Retrieves the current status of a specific bulk processing operation.
     *
     * @param id The unique identifier of the operation (processing_id) to check its status.
     * @return A ResponseEntity with the bulk processing status payload.
     */
    @GetMapping("/status/{processing_id}")
    public ResponseEntity<BulkStatus> getUploadStatus(@PathVariable("processing_id") Integer id) {
        return ResponseEntity.ok(bulkProcessingService.getStatus(id));
    }

    /**
     * Handles the upload of a file for a specific processing type and file type.
     *
     * @param processingType The processing type ("full" or "append") associated with the upload.
     * @param type           The file type being uploaded, as defined in {@link BulkFileType}.
     * @param file           The file to be uploaded, provided as a multipart file.
     * @return A ResponseEntity indicating whether the upload was processed successfully.
     */
    @PostMapping("/upload/{type}/{processing_type}")
    public ResponseEntity<Integer> uploadFile(@PathVariable("processing_type") BulkProcessingType processingType, @PathVariable BulkFileType type, @RequestParam("file") MultipartFile file) {
        return ResponseEntity.ok(bulkProcessingService.processFile(type, processingType, file));
    }

    /**
     * Generates and downloads a template file for the specified file type.
     *
     * @param type The type of file template to generate, based on the {@link BulkFileType} enumeration.
     * @return A ResponseEntity with the generated template as an InputStreamResource.
     * The response includes the appropriate Excel MIME type and a Content-Disposition header
     * specifying it as a downloadable file.
     * @throws IllegalArgumentException if the file type is invalid.
     */
    @GetMapping("/templates/{type}")
    public ResponseEntity<InputStreamResource> generateTemplate(@PathVariable BulkFileType type) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=lcc_template_" + type.name().toLowerCase() + ".xlsx");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(new InputStreamResource(templateExportService.generateTemplate(BulkFileType.valueOf(type.name().toUpperCase()))));
    }

    /**
     * Downloads an export file for the specified file type.
     *
     * @param type The type of file to export, as defined in {@link BulkFileType}.
     * @return A ResponseEntity with the exported file as an InputStreamResource.
     * The file is served as an Excel document, with proper headers for download.
     * @throws IllegalArgumentException if the provided file type is not supported.
     */
    @GetMapping("/download/{type}")
    public ResponseEntity<InputStreamResource> downloadFile(@PathVariable BulkFileType type) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=lcc_export_" + type.name().toLowerCase() + ".xlsx");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(new InputStreamResource(bulkExportService.generateExport(BulkFileType.valueOf(type.name().toUpperCase()))));
    }

    /**
     * Downloads an export file for the specified file type, filtered by a validity period.
     *
     * @param type             The type of file to export, according to {@link BulkFileType}.
     * @param validityPeriodId The ID of the validity period to apply filtering for the export.
     * @return A ResponseEntity containing the exported file as an InputStreamResource.
     * The file is served as an Excel document, with appropriate headers for download.
     * @throws IllegalArgumentException if the file type or validity period ID is invalid.
     */
    @GetMapping("/download/{type}/{validity_period_id}")
    public ResponseEntity<InputStreamResource> downloadFile(@PathVariable BulkFileType type, @PathVariable("validity_period_id") Integer validityPeriodId) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment; filename=lcc_export_" + type.name().toLowerCase() + ".xlsx");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.parseMediaType("application/vnd.ms-excel"))
                .body(new InputStreamResource(bulkExportService.generateExport(BulkFileType.valueOf(type.name().toUpperCase()), validityPeriodId)));
    }
}
