package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.service.OrganisationService;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
import org.jboss.logging.Logger;

import java.util.Map;
import java.util.UUID;

/**
 * API réservée au SUPER_ADMIN pour associer un utilisateur (par email) à une organisation.
 * Permet à un admin d'organisation de voir « Mes organisations » après connexion.
 */
@Path("/api/admin/associer-organisation")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Admin - Association", description = "Associer un utilisateur à une organisation (SUPER_ADMIN)")
@RolesAllowed("SUPER_ADMIN")
public class AdminAssocierOrganisationResource {

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

    @Inject
    OrganisationService organisationService;

    /**
     * Associe l'utilisateur ayant l'email donné à l'organisation indiquée.
     * Crée un Membre minimal si nécessaire, puis le lien MembreOrganisation (idempotent).
     */
    @POST
    @Operation(
        summary = "Associer un compte à une organisation",
        description = "En tant que super admin, associe l'utilisateur (email) à une organisation. "
            + "Si aucun Membre n'existe pour cet email, une fiche minimale est créée. "
            + "L'utilisateur pourra alors voir cette organisation dans « Mes organisations »."
    )
    public Response associerOrganisation(AssocierOrganisationRequest request) {
        if (request == null || request.email() == null || request.email().isBlank()) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(Map.of("error", "L'email est obligatoire"))
                .build();
        }
        if (request.organisationId() == null) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(Map.of("error", "L'organisation (organisationId) est obligatoire"))
                .build();
        }
        try {
            organisationService.associerUtilisateurAOrganisation(request.email().trim(), request.organisationId());
            LOG.infof("Association réussie: %s -> organisation %s", request.email(), request.organisationId());
            return Response.ok(Map.of(
                "success", true,
                "message", "Utilisateur associé à l'organisation avec succès.",
                "email", request.email(),
                "organisationId", request.organisationId().toString()
            )).build();
        } catch (jakarta.ws.rs.NotFoundException e) {
            return Response.status(Response.Status.NOT_FOUND)
                .entity(Map.of("error", "Non trouvé", "message", e.getMessage()))
                .build();
        } catch (IllegalArgumentException e) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(Map.of("error", "Requête invalide", "message", e.getMessage()))
                .build();
        } catch (Exception e) {
            LOG.errorf(e, "Erreur association organisation: %s", e.getMessage());
            return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity(Map.of("error", "Erreur serveur", "message", e.getMessage()))
                .build();
        }
    }

    /**
     * Corps de la requête pour associer un utilisateur à une organisation.
     */
    public record AssocierOrganisationRequest(
        @NotBlank(message = "L'email est obligatoire") String email,
        @NotNull(message = "L'organisation est obligatoire") UUID organisationId
    ) {}
}
