package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.api.dto.document.DocumentDTO;
import dev.lions.unionflow.server.api.dto.document.PieceJointeDTO;
import dev.lions.unionflow.server.service.DocumentService;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
import java.util.UUID;
import org.jboss.logging.Logger;

/**
 * Resource REST pour la gestion documentaire
 *
 * @author UnionFlow Team
 * @version 3.0
 * @since 2025-01-29
 */
@Path("/api/documents")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed({"ADMIN", "MEMBRE", "USER"})
public class DocumentResource {

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

  @Inject DocumentService documentService;

  /**
   * Crée un nouveau document
   *
   * @param documentDTO DTO du document à créer
   * @return Document créé
   */
  @POST
  @RolesAllowed({"ADMIN", "MEMBRE"})
  public Response creerDocument(@Valid DocumentDTO documentDTO) {
    try {
      DocumentDTO result = documentService.creerDocument(documentDTO);
      return Response.status(Response.Status.CREATED).entity(result).build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de la création du document");
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(new ErrorResponse("Erreur lors de la création du document: " + e.getMessage()))
          .build();
    }
  }

  /**
   * Trouve un document par son ID
   *
   * @param id ID du document
   * @return Document
   */
  @GET
  @Path("/{id}")
  public Response trouverParId(@PathParam("id") UUID id) {
    try {
      DocumentDTO result = documentService.trouverParId(id);
      return Response.ok(result).build();
    } catch (jakarta.ws.rs.NotFoundException e) {
      return Response.status(Response.Status.NOT_FOUND)
          .entity(new ErrorResponse("Document non trouvé"))
          .build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de la recherche du document");
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(new ErrorResponse("Erreur lors de la recherche du document: " + e.getMessage()))
          .build();
    }
  }

  /**
   * Enregistre un téléchargement de document
   *
   * @param id ID du document
   * @return Succès
   */
  @POST
  @RolesAllowed({"ADMIN", "MEMBRE"})
  @Path("/{id}/telechargement")
  public Response enregistrerTelechargement(@PathParam("id") UUID id) {
    try {
      documentService.enregistrerTelechargement(id);
      return Response.ok().build();
    } catch (jakarta.ws.rs.NotFoundException e) {
      return Response.status(Response.Status.NOT_FOUND)
          .entity(new ErrorResponse("Document non trouvé"))
          .build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de l'enregistrement du téléchargement");
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(
              new ErrorResponse(
                  "Erreur lors de l'enregistrement du téléchargement: " + e.getMessage()))
          .build();
    }
  }

  /**
   * Crée une pièce jointe
   *
   * @param pieceJointeDTO DTO de la pièce jointe à créer
   * @return Pièce jointe créée
   */
  @POST
  @RolesAllowed({"ADMIN", "MEMBRE"})
  @Path("/pieces-jointes")
  public Response creerPieceJointe(@Valid PieceJointeDTO pieceJointeDTO) {
    try {
      PieceJointeDTO result = documentService.creerPieceJointe(pieceJointeDTO);
      return Response.status(Response.Status.CREATED).entity(result).build();
    } catch (IllegalArgumentException e) {
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(new ErrorResponse(e.getMessage()))
          .build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de la création de la pièce jointe");
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(new ErrorResponse("Erreur lors de la création de la pièce jointe: " + e.getMessage()))
          .build();
    }
  }

  /**
   * Liste toutes les pièces jointes d'un document
   *
   * @param documentId ID du document
   * @return Liste des pièces jointes
   */
  @GET
  @Path("/{documentId}/pieces-jointes")
  public Response listerPiecesJointesParDocument(@PathParam("documentId") UUID documentId) {
    try {
      List<PieceJointeDTO> result = documentService.listerPiecesJointesParDocument(documentId);
      return Response.ok(result).build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de la liste des pièces jointes");
      return Response.status(Response.Status.BAD_REQUEST)
          .entity(new ErrorResponse("Erreur lors de la liste des pièces jointes: " + e.getMessage()))
          .build();
    }
  }

  /** Classe interne pour les réponses d'erreur */
  public static class ErrorResponse {
    public String error;

    public ErrorResponse(String error) {
      this.error = error;
    }
  }
}

