package dev.lions.user.manager.api;

import dev.lions.user.manager.dto.importexport.ImportResultDTO;
import dev.lions.user.manager.dto.user.*;
import jakarta.validation.Valid;
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.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.parameters.Parameter;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;

import java.util.List;

/**
 * Interface JAX-RS pour la gestion des utilisateurs.
 */
@Path("/api/users")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Users", description = "Gestion des utilisateurs Keycloak")
public interface UserResourceApi {

    @POST
    @Path("/search")
    @Operation(summary = "Rechercher des utilisateurs", description = "Recherche d'utilisateurs selon des critères")
    UserSearchResultDTO searchUsers(@Valid @NotNull UserSearchCriteriaDTO criteria);

    @GET
    @Path("/{userId}")
    @Operation(summary = "Récupérer un utilisateur par ID", description = "Récupère les détails d'un utilisateur")
    UserDTO getUserById(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
            @Parameter(description = "Nom du realm") @QueryParam("realm") String realmName);

    @GET
    @Operation(summary = "Lister tous les utilisateurs", description = "Liste paginée de tous les utilisateurs")
    UserSearchResultDTO getAllUsers(
            @QueryParam("realm") String realmName,
            @QueryParam("page") @DefaultValue("0") int page,
            @QueryParam("pageSize") @DefaultValue("20") int pageSize);

    @POST
    @Operation(summary = "Créer un utilisateur", description = "Crée un nouvel utilisateur dans Keycloak")
    @APIResponses({
            @APIResponse(responseCode = "201", description = "Utilisateur créé", content = @Content(schema = @Schema(implementation = UserDTO.class)))
    })
    Response createUser(
            @Valid @NotNull UserDTO user,
            @QueryParam("realm") String realmName);

    @PUT
    @Path("/{userId}")
    @Operation(summary = "Mettre à jour un utilisateur", description = "Met à jour les informations d'un utilisateur")
    UserDTO updateUser(
            @PathParam("userId") String userId,
            @Valid @NotNull UserDTO user,
            @QueryParam("realm") String realmName);

    @DELETE
    @Path("/{userId}")
    @Operation(summary = "Supprimer un utilisateur", description = "Supprime un utilisateur (soft ou hard delete)")
    void deleteUser(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName,
            @QueryParam("hardDelete") @DefaultValue("false") boolean hardDelete);

    @POST
    @Path("/{userId}/activate")
    @Operation(summary = "Activer un utilisateur", description = "Active un utilisateur désactivé")
    void activateUser(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName);

    @POST
    @Path("/{userId}/deactivate")
    @Operation(summary = "Désactiver un utilisateur", description = "Désactive un utilisateur")
    void deactivateUser(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName,
            @QueryParam("raison") String raison);

    @POST
    @Path("/{userId}/reset-password")
    @Operation(summary = "Réinitialiser le mot de passe", description = "Définit un nouveau mot de passe pour l'utilisateur")
    void resetPassword(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName,
            @NotNull PasswordResetRequestDTO request);

    @POST
    @Path("/{userId}/send-verification-email")
    @Operation(summary = "Envoyer email de vérification", description = "Envoie un email de vérification à l'utilisateur")
    void sendVerificationEmail(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName);

    @POST
    @Path("/{userId}/logout-sessions")
    @Operation(summary = "Déconnecter toutes les sessions", description = "Révoque toutes les sessions actives de l'utilisateur")
    SessionsRevokedDTO logoutAllSessions(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName);

    @GET
    @Path("/{userId}/sessions")
    @Operation(summary = "Récupérer les sessions actives", description = "Liste les sessions actives de l'utilisateur")
    @APIResponses({
            @APIResponse(responseCode = "200", description = "Liste des sessions", content = @Content(schema = @Schema(type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY, implementation = String.class)))
    })
    List<String> getActiveSessions(
            @PathParam("userId") String userId,
            @QueryParam("realm") String realmName);

    @GET
    @Path("/export/csv")
    @Produces("text/csv")
    @Operation(summary = "Exporter les utilisateurs en CSV", description = "Exporte la liste des utilisateurs du realm au format CSV")
    Response exportUsersToCSV(@QueryParam("realm") String realmName);

    @POST
    @Path("/import/csv")
    @Consumes(MediaType.TEXT_PLAIN)
    @Produces(MediaType.APPLICATION_JSON)
    @Operation(summary = "Importer des utilisateurs depuis un CSV", description = "Importe des utilisateurs à partir d'un fichier CSV")
    ImportResultDTO importUsersFromCSV(
            @QueryParam("realm") String realmName,
            String csvContent);
}
