package de.frigosped.dc.resource;

import de.frigosped.dc.model.CatalogGenerateResponse;
import de.frigosped.dc.model.OrdsCatalogStatusResponse;
import de.frigosped.dc.service.CatalogGenerationService;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import de.frigosped.dc.client.OrdsClient;
import org.jboss.logging.Logger;
import org.jboss.resteasy.reactive.RestForm;
import org.jboss.resteasy.reactive.multipart.FileUpload;

import java.nio.file.Files;

/**
 * REST-Endpunkte zur automatischen Fragenkatalog-Generierung.
 *
 * POST /catalog/generate          → 202 Accepted, Verarbeitung läuft asynchron
 * GET  /catalog/status/{catalogId} → Aktueller Status (GENERATING | READY | ERROR)
 *
 * curl-Beispiel:
 *   # Starten:
 *   curl -X POST http://localhost:8090/catalog/generate \
 *     -F "file=@ADSp-2017.pdf;type=application/pdf" \
 *     -F "catalog_name=ADSp 2017" \
 *     -F "document_type_id=1" \
 *     -F "description=Allgemeine Deutsche Spediteurbedingungen 2017"
 *
 *   # Status prüfen:
 *   curl http://localhost:8090/catalog/status/42
 */
@Path("/catalog")
@Produces(MediaType.APPLICATION_JSON)
public class CatalogResource {

    private static final Logger LOG = Logger.getLogger(CatalogResource.class);

    @Inject
    CatalogGenerationService catalogGenerationService;

    @Inject
    @RestClient
    OrdsClient ordsClient;

    /**
     * POST /catalog/generate  (multipart/form-data)
     * Gibt sofort 202 Accepted zurück. Verarbeitung läuft im Hintergrund.
     *
     * Response: {"catalog_id": 42, "catalog_name": "ADSp 2017",
     *            "description": "...", "generation_status": "GENERATING"}
     */
    @POST
    @Path("/generate")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response generate(
            @RestForm FileUpload file,
            @RestForm("catalog_name") String catalogName,
            @RestForm("document_type_id") Long documentTypeId,
            @RestForm String description) {

        if (file == null || file.uploadedFile() == null) {
            return badRequest("file ist ein Pflichtfeld.");
        }
        if (catalogName == null || catalogName.isBlank()) {
            return badRequest("catalog_name ist ein Pflichtfeld.");
        }
        if (documentTypeId == null) {
            return badRequest("document_type_id ist ein Pflichtfeld.");
        }

        try {
            // Bytes jetzt lesen – Temp-Datei wird nach Request-Ende ggf. gelöscht
            byte[] fileBytes = Files.readAllBytes(file.uploadedFile());
            String mimeType  = file.contentType();
            String filename  = file.fileName() != null ? file.fileName() : "dokument";
            String desc      = description != null ? description.trim() : null;
            String name      = catalogName.trim();

            LOG.infof("Katalog-Generierung angefordert: name='%s', file='%s' (%d Bytes)",
                    name, filename, fileBytes.length);

            long catalogId = catalogGenerationService.startGeneration(
                    fileBytes, mimeType, filename, name, desc, documentTypeId);

            return Response.accepted(
                    new CatalogGenerateResponse(catalogId, name, desc, "GENERATING")).build();

        } catch (Exception e) {
            LOG.errorf(e, "Fehler beim Start der Katalog-Generierung für '%s'", catalogName);
            return serverError(e.getMessage());
        }
    }

    /**
     * GET /catalog/status/{catalogId}
     * Fragt den aktuellen Generierungsstatus aus der DB ab.
     *
     * Response: {"catalog_id": 42, "name": "ADSp 2017",
     *            "generation_status": "READY", "generation_error": null}
     */
    @GET
    @Path("/status/{catalogId}")
    public Response status(@PathParam("catalogId") long catalogId) {
        try {
            OrdsCatalogStatusResponse statusResp = ordsClient.getCatalogStatus(catalogId);
            if (statusResp == null || statusResp.getCatalogId() == null) {
                return Response.status(Response.Status.NOT_FOUND)
                        .entity("{\"error\":\"Katalog nicht gefunden\",\"catalog_id\":"
                                + catalogId + "}")
                        .build();
            }
            return Response.ok(statusResp).build();
        } catch (Exception e) {
            LOG.errorf(e, "Fehler beim Status-Abruf für Katalog %d", catalogId);
            return serverError(e.getMessage());
        }
    }

    private Response badRequest(String message) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity("{\"error\":\"" + escapeJson(message) + "\"}")
                .build();
    }

    private Response serverError(String message) {
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity("{\"error\":\"" + escapeJson(message) + "\"}")
                .build();
    }

    private String escapeJson(String s) {
        if (s == null) return "";
        return s.replace("\\", "\\\\").replace("\"", "'").replace("\n", " ");
    }
}
