package com.trackingpremium.report.controller;

import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.trackingpremium.report.dto.CompanyRequest;
import com.trackingpremium.report.dto.ReportDetail;
import com.trackingpremium.report.dto.ReportResponse;
import com.trackingpremium.report.service.ReportService;

import jakarta.servlet.http.HttpServletResponse;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;

@RestController
@RequestMapping("/reports")
public class ReportController {

    private final ReportService reportService;
    private static final String TEMP_DIR = System.getProperty("java.io.tmpdir") + "/tp_reports";
    private static final String[] ALLOWED_DOCUMENT_TYPES = { "Guide", "Receipt", "Warehouse", "LoadUnit", "Consolidated", "Lockers", "Invoice", "Location", "Payment", "Dashboard", "Pickup", "ShippingRequests"};
    private static final String[] ALLOWED_DOCUMENT_FORMATS = { "html", "pdf", "xlsx", "csv" };
    
    @Autowired
    public ReportController(ReportService reportService) {
        this.reportService = reportService;
    }

    private boolean validateAllowedValue(String value, String[] allowedValues) {
        for (String allowedValue : allowedValues) {
            if (value.equals(allowedValue)) {
                return true;
            }
        }
        return false;
    }

    private ResponseEntity<?> createErrorResponse(String error, String message) {
        Map<String, String> errorResponse = new HashMap<>();
        errorResponse.put("error", error);
        errorResponse.put("message", message);
        return ResponseEntity.badRequest().body(errorResponse);
    }

    /**
     * Example body:
     * {
     * "company": "test", // Acronym of the company
     * "type": "Guide", // Guide, Receipt, Warehouse
     * "name": "PDFdefaultBase", // Name of the report
     * "format": "html", // html, pdf, xlsx, csv
     * "params": {
     * "language": "en",
     * "documentId": "8416" // ID of the document to generate the report for
     * }
     * }
     */
    @PostMapping("/generate")
    public ResponseEntity<?> generateReport(HttpServletResponse response, @RequestBody Map<String, Object> requestBody)
            throws Exception {    	
        try {
            String company = (String) requestBody.get("company");
            String type = (String) requestBody.get("type");
            String name = (String) requestBody.get("name");
            String format = (String) requestBody.get("format");
            
            @SuppressWarnings("unchecked")
            Map<String, Object> params = (Map<String, Object>) requestBody.get("params");                                  

            if (company == null || company.trim().isEmpty()) {
                return createErrorResponse("Required parameter", "The 'company' parameter cannot be null or empty");
            }

            if (name == null || name.trim().isEmpty()) {
                return createErrorResponse("Required parameter", "The 'name' parameter cannot be null or empty");
            }

            if (type == null || type.trim().isEmpty()) {
                return createErrorResponse("Required parameter", "The 'type' parameter cannot be null or empty");
            }

            boolean isValidType = validateAllowedValue(type, ALLOWED_DOCUMENT_TYPES);
            if (!isValidType) {
                return createErrorResponse("Invalid value",
                        "The 'type' parameter must be one of the following values: "
                                + String.join(", ", ALLOWED_DOCUMENT_TYPES));
            }

            if (format == null || format.trim().isEmpty()) {
                return createErrorResponse("Required parameter", "The 'format' parameter cannot be null or empty");
            }

            boolean isValidFormat = validateAllowedValue(format, ALLOWED_DOCUMENT_FORMATS);
            if (!isValidFormat) {
                return createErrorResponse("Invalid value",
                        "The 'format' parameter must be one of the following values: "
                                + String.join(", ", ALLOWED_DOCUMENT_FORMATS));
            }

            if (format.equalsIgnoreCase("html")) {
            	String reportUrl = reportService.generateReport(company, type, name, params, format);
                Map<String, String> responseBody = new HashMap<>();
                responseBody.put("url", reportUrl);
                return ResponseEntity.ok(responseBody);
            } else {
                reportService.generateReport(response, company, type, name, params, format);
                return ResponseEntity.ok().build();
            }
        } catch (Exception e) {
            if (e.getMessage() != null && e.getMessage().contains("Could not find Jasper file")) {
                Map<String, String> errorResponse = new HashMap<>();
                errorResponse.put("error", "Report not found");
                errorResponse.put("message", "The requested report does not exist in the system "+e.getMessage());
                return ResponseEntity.status(HttpServletResponse.SC_NOT_FOUND).body(errorResponse);
            }
            throw e;
        }
    }
    
   
    @GetMapping("/html/{filename}")
    public ResponseEntity<Resource> getHtmlReport(@PathVariable String filename) {
        try {
            Path filePath = Paths.get(TEMP_DIR, filename);
            Resource resource = new UrlResource(filePath.toUri());

            if (resource.exists() && resource.isReadable()) {
                return ResponseEntity.ok()
                        .header("Content-Type", "text/html")
                        .body(resource);
            } else {
                return ResponseEntity.notFound().build();
            }
        } catch (Exception e) {
            return ResponseEntity.notFound().build();
        }
    }
    
    /**
     * Endpoint para obtener la lista de reportes personalizados de una empresa.
     * URL: /reports/custom/nombre_empresa
     */
    /*logica para el servicio que está comentado */
    @PostMapping("/list-custom-by-type")
    public ResponseEntity<List<ReportResponse>> getCustomReportsByType(@RequestBody CompanyRequest request) {
    	/* en reserva */
        // Obtenemos la lista usando el nombre que viene en el JSON
    	List<ReportResponse> reportes = reportService.obtenerReportesPersonalizadosPorTipo(request);
        
        if (reportes.isEmpty()) {
            return ResponseEntity.noContent().build();
        }
        
        return ResponseEntity.ok(reportes);
    }
    @PostMapping("/list-custom")
    public ResponseEntity<Map<String, List<ReportDetail>>> getCustomReports(@RequestBody CompanyRequest request) {
    	/*en uso */
    	Map<String, List<ReportDetail>> resultado = reportService.obtenerReportesAgrupados(request);
        return ResponseEntity.ok(resultado);
    }
    
}