package dev.lions.user.manager.api;

import dev.lions.user.manager.dto.realm.AuthorizedRealmsDTO;
import dev.lions.user.manager.dto.realm.RealmAccessCheckDTO;
import dev.lions.user.manager.dto.realm.RealmAssignmentDTO;
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 l'API de gestion des affectations de realms.
 */
@Path("/api/realm-assignments")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Realm Assignments", description = "Gestion des affectations de realms (contrôle d'accès multi-tenant)")
public interface RealmAssignmentResourceApi {

    @GET
    @Operation(summary = "Lister toutes les affectations", description = "Liste toutes les affectations de realms")
    List<RealmAssignmentDTO> getAllAssignments();

    @GET
    @Path("/user/{userId}")
    @Operation(summary = "Affectations par utilisateur", description = "Liste les realms assignés à un utilisateur")
    List<RealmAssignmentDTO> getAssignmentsByUser(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);

    @GET
    @Path("/realm/{realmName}")
    @Operation(summary = "Affectations par realm", description = "Liste les utilisateurs ayant accès à un realm")
    List<RealmAssignmentDTO> getAssignmentsByRealm(
            @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);

    @GET
    @Path("/{assignmentId}")
    @Operation(summary = "Récupérer une affectation", description = "Récupère une affectation par son ID")
    RealmAssignmentDTO getAssignmentById(
            @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);

    @GET
    @Path("/check")
    @Operation(summary = "Vérifier l'accès", description = "Vérifie si un utilisateur peut gérer un realm")
    RealmAccessCheckDTO canManageRealm(
            @Parameter(description = "ID de l'utilisateur") @QueryParam("userId") String userId,
            @Parameter(description = "Nom du realm") @QueryParam("realmName") String realmName);

    @GET
    @Path("/authorized-realms/{userId}")
    @Operation(summary = "Realms autorisés", description = "Liste les realms qu'un utilisateur peut gérer")
    AuthorizedRealmsDTO getAuthorizedRealms(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);

    @POST
    @Operation(summary = "Assigner un realm", description = "Assigne un realm à un utilisateur")
    @APIResponses({
            @APIResponse(responseCode = "201", description = "Affectation créée", content = @Content(schema = @Schema(implementation = RealmAssignmentDTO.class)))
    })
    Response assignRealmToUser(@Valid @NotNull RealmAssignmentDTO assignment);

    @DELETE
    @Path("/user/{userId}/realm/{realmName}")
    @Operation(summary = "Révoquer un realm", description = "Retire l'accès d'un utilisateur à un realm")
    void revokeRealmFromUser(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
            @Parameter(description = "Nom du realm") @PathParam("realmName") String realmName);

    @DELETE
    @Path("/user/{userId}")
    @Operation(summary = "Révoquer tous les realms", description = "Retire tous les accès d'un utilisateur")
    void revokeAllRealmsFromUser(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId);

    @PUT
    @Path("/{assignmentId}/deactivate")
    @Operation(summary = "Désactiver une affectation", description = "Désactive une affectation sans la supprimer")
    void deactivateAssignment(
            @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);

    @PUT
    @Path("/{assignmentId}/activate")
    @Operation(summary = "Activer une affectation", description = "Réactive une affectation")
    void activateAssignment(
            @Parameter(description = "ID de l'affectation") @PathParam("assignmentId") String assignmentId);

    @PUT
    @Path("/super-admin/{userId}")
    @Operation(summary = "Définir super admin", description = "Définit ou retire le statut de super admin")
    void setSuperAdmin(
            @Parameter(description = "ID de l'utilisateur") @PathParam("userId") String userId,
            @Parameter(description = "Super admin (true/false)") @QueryParam("superAdmin") @NotNull Boolean superAdmin);
}
