package de.frigosped.dc.client;

import de.frigosped.dc.model.*;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;

/**
 * MicroProfile REST Client für die ORDS /api/dc/-Endpunkte.
 *
 * Basis-URL wird in application.properties gesetzt:
 *   quarkus.rest-client.ords-api.url=http://host/ords/SCHEMA
 *
 * Optionaler Bearer-Token für Produktion:
 *   dc.ords.bearer-token=eyJ...
 *   → @ClientHeaderParam(name = "Authorization", value = "${dc.ords.bearer-token}")
 */
@RegisterRestClient(configKey = "ords-api")
@RegisterProvider(OrdsLoggingFilter.class)
@Path("/api/dc")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface OrdsClient {

    // =========================================================================
    // Fragenkatalog (Lesend + Schreibend)
    // =========================================================================

    /**
     * GET /api/dc/catalogs/:catalogId/questions/
     * Liefert alle Fragen (mit Kategorie-Info) für einen Katalog.
     */
    @GET
    @Path("/catalogs/{catalogId}/questions/")
    OrdsQuestionList getQuestions(@PathParam("catalogId") long catalogId);

    /**
     * POST /api/dc/catalogs/
     * Legt einen neuen Fragenkatalog an.
     * Antwort: 201 Created, Body {"id": <new_id>, "name": "...", ...}
     */
    @POST
    @Path("/catalogs/")
    Response createCatalog(OrdsCatalogCreateRequest body);

    /**
     * POST /api/dc/catalogs/:catalogId/categories/
     * Legt eine neue Fragenkategorie in einem Katalog an.
     * Antwort: 201 Created, Body {"id": <new_id>, ...}
     */
    @POST
    @Path("/catalogs/{catalogId}/categories/")
    Response createCategory(@PathParam("catalogId") long catalogId,
                            OrdsCategoryCreateRequest body);

    /**
     * POST /api/dc/categories/:categoryId/questions/
     * Legt eine neue Frage in einer Kategorie an.
     * Antwort: 201 Created, Body {"id": <new_id>, ...}
     */
    @POST
    @Path("/categories/{categoryId}/questions/")
    Response createQuestion(@PathParam("categoryId") long categoryId,
                            OrdsQuestionCreateRequest body);

    /**
     * GET /api/dc/catalogs/:catalogId/generation-status
     * Liest den Generierungsstatus (GENERATING | READY | ERROR).
     */
    @GET
    @Path("/catalogs/{catalogId}/generation-status")
    OrdsCatalogStatusResponse getCatalogStatus(@PathParam("catalogId") long catalogId);

    /**
     * PUT /api/dc/catalogs/:catalogId/generation-status
     * Setzt den Generierungsstatus nach Abschluss oder Fehler.
     */
    @PUT
    @Path("/catalogs/{catalogId}/generation-status")
    Response updateCatalogStatus(@PathParam("catalogId") long catalogId,
                                 OrdsCatalogStatusUpdateRequest body);

    // =========================================================================
    // Projekte (Status-Steuerung)
    // =========================================================================

    /**
     * GET /api/dc/projects/:projectId
     * Projektdetails laden (Status, catalog_id, notification_email, ...).
     */
    @GET
    @Path("/projects/{projectId}")
    OrdsProject getProject(@PathParam("projectId") long projectId);

    /**
     * POST /api/dc/projects/:projectId/start
     * Setzt Status auf IN_PROGRESS. 409 wenn nicht PENDING.
     */
    @POST
    @Path("/projects/{projectId}/start")
    Response startProject(@PathParam("projectId") long projectId);

    /**
     * PUT /api/dc/projects/:projectId/progress
     * Aktualisiert den Fortschritt (0–100).
     */
    @PUT
    @Path("/projects/{projectId}/progress")
    Response updateProgress(@PathParam("projectId") long projectId,
                            ProgressRequest body);

    /**
     * POST /api/dc/projects/:projectId/complete
     * Setzt Status auf COMPLETED + completed_at = SYSDATE.
     * Body enthält optional das vorberechnete report_markdown.
     */
    @POST
    @Path("/projects/{projectId}/complete")
    Response completeProject(@PathParam("projectId") long projectId,
                             CompleteProjectRequest body);

    // =========================================================================
    // Dokumente
    // =========================================================================

    /**
     * GET /api/dc/projects/:projectId/documents/
     * Liste aller Dokumente (Metadaten, kein BLOB).
     */
    @GET
    @Path("/projects/{projectId}/documents/")
    OrdsDocumentList getDocuments(@PathParam("projectId") long projectId);

    /**
     * GET /api/dc/documents/:docId/file
     * Download des Original-BLOBs.
     * Content-Type wird von ORDS aus mime_type-Spalte gesetzt.
     */
    @GET
    @Path("/documents/{docId}/file")
    @Produces(MediaType.WILDCARD)
    Response downloadFile(@PathParam("docId") long docId);

    /**
     * GET /api/dc/documents/:docId/texts
     * Liest original_text und translated_text (für Resume nach Phase A).
     */
    @GET
    @Path("/documents/{docId}/texts")
    OrdsDocumentTexts getTexts(@PathParam("docId") long docId);

    /**
     * PUT /api/dc/documents/:docId/texts
     * Schreibt original_text und/oder translated_text zurück.
     */
    @PUT
    @Path("/documents/{docId}/texts")
    Response updateTexts(@PathParam("docId") long docId, TextsRequest body);

    /**
     * PUT /api/dc/documents/:docId/progress
     * Setzt status und/oder progress (0-100) eines Dokuments.
     */
    @PUT
    @Path("/documents/{docId}/progress")
    Response updateDocumentProgress(@PathParam("docId") long docId, DocumentProgressRequest body);

    /**
     * POST /api/dc/documents/:parentId/references
     * Legt eine heruntergeladene externe Referenz als neue dc_project_documents-Zeile an.
     * Antwort: 201 Created, Body {"id": <new_id>, ...}
     */
    @POST
    @Path("/documents/{parentId}/references")
    Response insertReference(@PathParam("parentId") long parentId, ReferenceCreateRequest body);

    /**
     * DELETE /api/dc/projects/:projectId/references
     * Löscht alle heruntergeladenen Referenzen eines Projekts (vor Re-Processing).
     */
    @DELETE
    @Path("/projects/{projectId}/references")
    Response deleteReferences(@PathParam("projectId") long projectId);

    // =========================================================================
    // Ergebnisse
    // =========================================================================

    /**
     * POST /api/dc/projects/:projectId/results
     * Einzelnes Prüfergebnis speichern.
     */
    @POST
    @Path("/projects/{projectId}/results")
    Response saveResult(@PathParam("projectId") long projectId,
                        ResultRequest body);

    /**
     * DELETE /api/dc/projects/:projectId/results
     * Alle Ergebnisse löschen (vor Re-Processing).
     */
    @DELETE
    @Path("/projects/{projectId}/results")
    Response deleteResults(@PathParam("projectId") long projectId);

    // =========================================================================
    // KI-Kostenverfolgung
    // =========================================================================

    /**
     * POST /api/dc/ai-costs
     * Speichert einen KI-Aufruf mit Token-Verbrauch und Kosten in dc_ai_cost_log.
     */
    @POST
    @Path("/ai-costs")
    Response logAiCost(AiCostRequest body);
}
