package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.api.dto.notification.NotificationDTO;
import dev.lions.unionflow.server.api.enums.notification.TypeNotification;
import dev.lions.unionflow.server.service.NotificationService;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.jboss.logging.Logger;

/** Resource REST pour la gestion des notifications */
@Path("/api/notifications")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApplicationScoped
@Tag(name = "Notifications", description = "API de gestion des notifications")
public class NotificationResource {

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

  @Inject NotificationService notificationService;

  @POST
  @Operation(summary = "Envoyer une notification")
  @APIResponse(responseCode = "200", description = "Notification envoyée")
  public Response envoyerNotification(NotificationDTO notification) {
    LOG.infof("Envoi de notification: %s", notification.getTitre());
    try {
      CompletableFuture<NotificationDTO> future = notificationService.envoyerNotification(notification);
      NotificationDTO result = future.get();
      return Response.ok(result).build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de l'envoi de notification");
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
          .entity(Map.of("message", e.getMessage()))
          .build();
    }
  }

  @POST
  @Path("/groupe")
  @Operation(summary = "Envoyer une notification à un groupe")
  @APIResponse(responseCode = "200", description = "Notifications envoyées")
  public Response envoyerNotificationGroupe(
      @QueryParam("type") TypeNotification type,
      @QueryParam("titre") String titre,
      @QueryParam("message") String message,
      List<String> destinatairesIds) {
    LOG.infof("Envoi de notification de groupe: %d destinataires", destinatairesIds.size());
    try {
      CompletableFuture<List<NotificationDTO>> future =
          notificationService.envoyerNotificationGroupe(type, titre, message, destinatairesIds, Map.of());
      List<NotificationDTO> results = future.get();
      return Response.ok(results).build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de l'envoi de notifications groupées");
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
          .entity(Map.of("message", e.getMessage()))
          .build();
    }
  }

  @GET
  @Path("/utilisateur/{utilisateurId}")
  @Operation(summary = "Obtenir les notifications d'un utilisateur")
  @APIResponse(responseCode = "200", description = "Notifications récupérées")
  public Response obtenirNotifications(
      @PathParam("utilisateurId") String utilisateurId,
      @QueryParam("includeArchivees") @DefaultValue("false") boolean includeArchivees,
      @QueryParam("limite") @DefaultValue("50") int limite) {
    LOG.infof("Récupération notifications pour: %s", utilisateurId);
    List<NotificationDTO> notifications =
        notificationService.obtenirNotificationsUtilisateur(utilisateurId, includeArchivees, limite);
    return Response.ok(notifications).build();
  }

  @PUT
  @Path("/{notificationId}/lue")
  @Operation(summary = "Marquer une notification comme lue")
  @APIResponse(responseCode = "200", description = "Notification marquée comme lue")
  public Response marquerCommeLue(
      @PathParam("notificationId") String notificationId,
      @QueryParam("utilisateurId") String utilisateurId) {
    LOG.infof("Marquage comme lue: %s", notificationId);
    boolean succes = notificationService.marquerCommeLue(notificationId, utilisateurId);
    return Response.ok(Map.of("success", succes)).build();
  }

  @PUT
  @Path("/{notificationId}/archiver")
  @Operation(summary = "Archiver une notification")
  @APIResponse(responseCode = "200", description = "Notification archivée")
  public Response archiverNotification(
      @PathParam("notificationId") String notificationId,
      @QueryParam("utilisateurId") String utilisateurId) {
    LOG.infof("Archivage: %s", notificationId);
    boolean succes = notificationService.archiverNotification(notificationId, utilisateurId);
    return Response.ok(Map.of("success", succes)).build();
  }

  @GET
  @Path("/stats")
  @Operation(summary = "Obtenir les statistiques des notifications")
  @APIResponse(responseCode = "200", description = "Statistiques récupérées")
  public Response obtenirStatistiques() {
    Map<String, Long> stats = notificationService.obtenirStatistiques();
    return Response.ok(stats).build();
  }

  @POST
  @Path("/test/{utilisateurId}")
  @Operation(summary = "Envoyer une notification de test")
  @APIResponse(responseCode = "200", description = "Notification de test envoyée")
  public Response envoyerNotificationTest(
      @PathParam("utilisateurId") String utilisateurId,
      @QueryParam("type") @DefaultValue("SYSTEME") TypeNotification type) {
    LOG.infof("Envoi notification de test: %s", utilisateurId);
    try {
      CompletableFuture<NotificationDTO> future =
          notificationService.envoyerNotificationTest(utilisateurId, type);
      NotificationDTO result = future.get();
      return Response.ok(result).build();
    } catch (Exception e) {
      LOG.errorf(e, "Erreur lors de l'envoi de notification de test");
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
          .entity(Map.of("message", e.getMessage()))
          .build();
    }
  }
}

