package dev.lions.user.manager.api;

import dev.lions.user.manager.dto.audit.AuditLogDTO;
import dev.lions.user.manager.dto.common.CountDTO;
import dev.lions.user.manager.enums.audit.TypeActionAudit;
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;
import java.util.Map;

/**
 * Interface JAX-RS pour l'API d'audit.
 */
@Path("/api/audit")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Audit", description = "Consultation des logs d'audit et statistiques")
public interface AuditResourceApi {

    @POST
    @Path("/search")
    @Operation(summary = "Rechercher des logs d'audit", description = "Recherche avancée de logs selon critères")
    @APIResponses({
            @APIResponse(responseCode = "200", description = "Résultats de recherche", content = @Content(schema = @Schema(implementation = AuditLogDTO.class, type = org.eclipse.microprofile.openapi.annotations.enums.SchemaType.ARRAY))),
            @APIResponse(responseCode = "500", description = "Erreur serveur")
    })
    List<AuditLogDTO> searchLogs(
            @QueryParam("acteur") String acteurUsername,
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin,
            @QueryParam("typeAction") TypeActionAudit typeAction,
            @QueryParam("ressourceType") String ressourceType,
            @QueryParam("succes") Boolean succes,
            @QueryParam("page") @DefaultValue("0") int page,
            @QueryParam("pageSize") @DefaultValue("50") int pageSize);

    @GET
    @Path("/actor/{acteurUsername}")
    @Operation(summary = "Récupérer les logs d'un acteur", description = "Liste les derniers logs d'un utilisateur")
    List<AuditLogDTO> getLogsByActor(
            @Parameter(description = "Username de l'acteur") @PathParam("acteurUsername") String acteurUsername,
            @Parameter(description = "Nombre de logs à retourner") @QueryParam("limit") @DefaultValue("100") int limit);

    @GET
    @Path("/resource/{ressourceType}/{ressourceId}")
    @Operation(summary = "Récupérer les logs d'une ressource", description = "Liste les derniers logs d'une ressource spécifique")
    List<AuditLogDTO> getLogsByResource(
            @PathParam("ressourceType") String ressourceType,
            @PathParam("ressourceId") String ressourceId,
            @QueryParam("limit") @DefaultValue("100") int limit);

    @GET
    @Path("/action/{typeAction}")
    @Operation(summary = "Récupérer les logs par type d'action", description = "Liste les logs d'un type d'action spécifique")
    List<AuditLogDTO> getLogsByAction(
            @PathParam("typeAction") TypeActionAudit typeAction,
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin,
            @QueryParam("limit") @DefaultValue("100") int limit);

    @GET
    @Path("/stats/actions")
    @Operation(summary = "Statistiques par type d'action", description = "Retourne le nombre de logs par type d'action")
    Map<TypeActionAudit, Long> getActionStatistics(
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin);

    @GET
    @Path("/stats/users")
    @Operation(summary = "Statistiques par utilisateur", description = "Retourne le nombre d'actions par utilisateur")
    Map<String, Long> getUserActivityStatistics(
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin);

    @GET
    @Path("/stats/failures")
    @Operation(summary = "Comptage des échecs", description = "Retourne le nombre d'échecs sur une période")
    CountDTO getFailureCount(
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin);

    @GET
    @Path("/stats/success")
    @Operation(summary = "Comptage des succès", description = "Retourne le nombre de succès sur une période")
    CountDTO getSuccessCount(
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin);

    @GET
    @Path("/export/csv")
    @Produces(MediaType.TEXT_PLAIN)
    @Operation(summary = "Exporter les logs en CSV", description = "Génère un fichier CSV des logs d'audit")
    Response exportLogsToCSV(
            @QueryParam("dateDebut") String dateDebut,
            @QueryParam("dateFin") String dateFin);

    @DELETE
    @Path("/purge")
    @Operation(summary = "Purger les anciens logs", description = "Supprime les logs de plus de X jours")
    void purgeOldLogs(
            @QueryParam("joursAnciennete") @DefaultValue("90") int joursAnciennete);
}
