package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.api.dto.messagerie.request.BloquerMembreRequest;
import dev.lions.unionflow.server.api.dto.messagerie.request.DemarrerConversationDirecteRequest;
import dev.lions.unionflow.server.api.dto.messagerie.request.DemarrerConversationRoleRequest;
import dev.lions.unionflow.server.api.dto.messagerie.request.EnvoyerMessageRequest;
import dev.lions.unionflow.server.api.dto.messagerie.request.MettreAJourPolitiqueRequest;
import dev.lions.unionflow.server.api.dto.messagerie.response.ContactPolicyResponse;
import dev.lions.unionflow.server.api.dto.messagerie.response.ConversationResponse;
import dev.lions.unionflow.server.api.dto.messagerie.response.ConversationSummaryResponse;
import dev.lions.unionflow.server.api.dto.messagerie.response.MessageResponse;
import dev.lions.unionflow.server.service.MessagingService;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import java.util.List;
import java.util.UUID;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.jboss.logging.Logger;

/**
 * Resource REST pour la messagerie instantanée.
 *
 * <p>Endpoints :
 * <ul>
 *   <li>POST /api/messagerie/conversations/directe — démarrer conversation 1-1</li>
 *   <li>POST /api/messagerie/conversations/role — contacter un rôle officiel</li>
 *   <li>GET  /api/messagerie/conversations — mes conversations</li>
 *   <li>GET  /api/messagerie/conversations/{id} — détail + messages</li>
 *   <li>DELETE /api/messagerie/conversations/{id} — archiver</li>
 *   <li>POST /api/messagerie/conversations/{id}/messages — envoyer un message</li>
 *   <li>GET  /api/messagerie/conversations/{id}/messages — historique</li>
 *   <li>PUT  /api/messagerie/conversations/{id}/lire — marquer comme lu</li>
 *   <li>DELETE /api/messagerie/conversations/{cId}/messages/{mId} — supprimer message</li>
 *   <li>POST /api/messagerie/blocages — bloquer un membre</li>
 *   <li>DELETE /api/messagerie/blocages/{membreId} — débloquer</li>
 *   <li>GET  /api/messagerie/blocages — mes blocages</li>
 *   <li>GET  /api/messagerie/politique/{orgId} — politique de communication</li>
 *   <li>PUT  /api/messagerie/politique/{orgId} — mettre à jour (ADMIN)</li>
 * </ul>
 *
 * @author UnionFlow Team
 * @version 4.0
 * @since 2026-04-13
 */
@Path("/api/messagerie")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed({"ADMIN", "ADMIN_ORGANISATION", "MEMBRE"})
@Tag(name = "Messagerie", description = "Messagerie instantanée — conversations, messages, notes vocales")
public class MessagingResource {

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

    @Inject
    MessagingService messagingService;

    // ── Conversations ─────────────────────────────────────────────────────────

    @POST
    @Path("/conversations/directe")
    public Response demarrerConversationDirecte(@Valid DemarrerConversationDirecteRequest request) {
        LOG.infof("POST /api/messagerie/conversations/directe → destinataire: %s", request.destinataireId());
        ConversationResponse result = messagingService.demarrerConversationDirecte(request);
        return Response.status(Response.Status.CREATED).entity(result).build();
    }

    @POST
    @Path("/conversations/role")
    public Response demarrerConversationRole(@Valid DemarrerConversationRoleRequest request) {
        LOG.infof("POST /api/messagerie/conversations/role → rôle: %s, org: %s",
            request.roleCible(), request.organisationId());
        ConversationResponse result = messagingService.demarrerConversationRole(request);
        return Response.status(Response.Status.CREATED).entity(result).build();
    }

    @GET
    @Path("/conversations")
    public Response getMesConversations() {
        LOG.debug("GET /api/messagerie/conversations");
        List<ConversationSummaryResponse> result = messagingService.getMesConversations();
        return Response.ok(result).build();
    }

    @GET
    @Path("/conversations/{id}")
    public Response getConversation(@PathParam("id") UUID id) {
        LOG.infof("GET /api/messagerie/conversations/%s", id);
        ConversationResponse result = messagingService.getConversation(id);
        return Response.ok(result).build();
    }

    @DELETE
    @Path("/conversations/{id}")
    public Response archiverConversation(@PathParam("id") UUID id) {
        LOG.infof("DELETE /api/messagerie/conversations/%s", id);
        ConversationResponse result = messagingService.archiverConversation(id);
        return Response.ok(result).build();
    }

    // ── Messages ──────────────────────────────────────────────────────────────

    @POST
    @Path("/conversations/{id}/messages")
    public Response envoyerMessage(
            @PathParam("id") UUID conversationId,
            @Valid EnvoyerMessageRequest request) {
        LOG.infof("POST /api/messagerie/conversations/%s/messages", conversationId);
        MessageResponse result = messagingService.envoyerMessage(conversationId, request);
        return Response.status(Response.Status.CREATED).entity(result).build();
    }

    @GET
    @Path("/conversations/{id}/messages")
    public Response getMessages(
            @PathParam("id") UUID conversationId,
            @QueryParam("page") @DefaultValue("0") int page) {
        LOG.infof("GET /api/messagerie/conversations/%s/messages?page=%d", conversationId, page);
        List<MessageResponse> result = messagingService.getMessages(conversationId, page);
        return Response.ok(result).build();
    }

    @PUT
    @Path("/conversations/{id}/lire")
    public Response marquerLu(@PathParam("id") UUID conversationId) {
        LOG.infof("PUT /api/messagerie/conversations/%s/lire", conversationId);
        messagingService.marquerConversationLue(conversationId);
        return Response.noContent().build();
    }

    @DELETE
    @Path("/conversations/{conversationId}/messages/{messageId}")
    public Response supprimerMessage(
            @PathParam("conversationId") UUID conversationId,
            @PathParam("messageId") UUID messageId) {
        LOG.infof("DELETE /api/messagerie/conversations/%s/messages/%s", conversationId, messageId);
        messagingService.supprimerMessage(conversationId, messageId);
        return Response.noContent().build();
    }

    // ── Blocages ──────────────────────────────────────────────────────────────

    @POST
    @Path("/blocages")
    public Response bloquerMembre(@Valid BloquerMembreRequest request) {
        LOG.infof("POST /api/messagerie/blocages → bloquer: %s", request.membreABloquerId());
        messagingService.bloquerMembre(request);
        return Response.noContent().build();
    }

    @DELETE
    @Path("/blocages/{membreId}")
    public Response debloquerMembre(
            @PathParam("membreId") UUID membreId,
            @QueryParam("organisationId") UUID organisationId) {
        LOG.infof("DELETE /api/messagerie/blocages/%s", membreId);
        messagingService.debloquerMembre(membreId, organisationId);
        return Response.noContent().build();
    }

    @GET
    @Path("/blocages")
    public Response getMesBlocages() {
        LOG.debug("GET /api/messagerie/blocages");
        return Response.ok(messagingService.getMesBlocages()).build();
    }

    // ── Politique de communication ────────────────────────────────────────────

    @GET
    @Path("/politique/{organisationId}")
    public Response getPolitique(@PathParam("organisationId") UUID organisationId) {
        LOG.infof("GET /api/messagerie/politique/%s", organisationId);
        ContactPolicyResponse result = messagingService.getPolitique(organisationId);
        return Response.ok(result).build();
    }

    @PUT
    @Path("/politique/{organisationId}")
    @RolesAllowed({"ADMIN", "ADMIN_ORGANISATION"})
    public Response mettreAJourPolitique(
            @PathParam("organisationId") UUID organisationId,
            @Valid MettreAJourPolitiqueRequest request) {
        LOG.infof("PUT /api/messagerie/politique/%s", organisationId);
        ContactPolicyResponse result = messagingService.mettreAJourPolitique(organisationId, request);
        return Response.ok(result).build();
    }
}
