package dev.lions.unionflow.server.resource;

import dev.lions.unionflow.server.api.dto.system.request.UpdateSystemConfigRequest;
import dev.lions.unionflow.server.api.dto.system.response.CacheStatsResponse;
import dev.lions.unionflow.server.api.dto.system.response.SystemConfigResponse;
import dev.lions.unionflow.server.api.dto.logs.response.SystemMetricsResponse;
import dev.lions.unionflow.server.api.dto.system.response.SystemTestResultResponse;
import dev.lions.unionflow.server.service.SystemConfigService;
import dev.lions.unionflow.server.service.SystemMetricsService;
import jakarta.annotation.security.RolesAllowed;
import jakarta.inject.Inject;
import jakarta.validation.Valid;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.microprofile.openapi.annotations.Operation;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;

import java.util.Map;

/**
 * REST Resource pour la gestion de la configuration système
 */
@Slf4j
@Path("/api/system")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Tag(name = "Système", description = "Gestion de la configuration système")
public class SystemResource {

    @Inject
    SystemConfigService systemConfigService;

    @Inject
    SystemMetricsService systemMetricsService;

    /**
     * Récupérer la configuration système
     */
    @GET
    @Path("/config")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN", "MODERATEUR"})
    @Operation(summary = "Récupérer la configuration système", description = "Retourne la configuration système complète")
    public SystemConfigResponse getSystemConfig() {
        log.info("GET /api/system/config");
        return systemConfigService.getSystemConfig();
    }

    /**
     * Mettre à jour la configuration système
     */
    @PUT
    @Path("/config")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Mettre à jour la configuration système")
    public SystemConfigResponse updateSystemConfig(@Valid UpdateSystemConfigRequest request) {
        log.info("PUT /api/system/config");
        return systemConfigService.updateSystemConfig(request);
    }

    /**
     * Récupérer les statistiques du cache
     */
    @GET
    @Path("/cache/stats")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN", "MODERATEUR"})
    @Operation(summary = "Récupérer les statistiques du cache système")
    public CacheStatsResponse getCacheStats() {
        log.info("GET /api/system/cache/stats");
        return systemConfigService.getCacheStats();
    }

    /**
     * Vider le cache système
     */
    @POST
    @Path("/cache/clear")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Vider le cache système")
    public Response clearCache() {
        log.info("POST /api/system/cache/clear");
        systemConfigService.clearCache();
        return Response.ok().entity(java.util.Map.of("message", "Cache vidé avec succès")).build();
    }

    /**
     * Tester la connexion à la base de données
     */
    @POST
    @Path("/test/database")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Tester la connexion à la base de données")
    public SystemTestResultResponse testDatabaseConnection() {
        log.info("POST /api/system/test/database");
        return systemConfigService.testDatabaseConnection();
    }

    /**
     * Tester la configuration email
     */
    @POST
    @Path("/test/email")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Tester la configuration email")
    public SystemTestResultResponse testEmailConfiguration() {
        log.info("POST /api/system/test/email");
        return systemConfigService.testEmailConfiguration();
    }

    /**
     * Récupérer les métriques système en temps réel
     */
    @GET
    @Path("/metrics")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN", "MODERATEUR"})
    @Operation(
        summary = "Récupérer les métriques système en temps réel",
        description = "Retourne toutes les métriques système (CPU, RAM, disque, utilisateurs actifs, etc.)"
    )
    public SystemMetricsResponse getSystemMetrics() {
        log.info("GET /api/system/metrics");
        return systemMetricsService.getSystemMetrics();
    }

    /**
     * Optimiser la base de données
     */
    @POST
    @Path("/database/optimize")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Optimiser la base de données (VACUUM ANALYZE)")
    public Response optimizeDatabase() {
        log.info("POST /api/system/database/optimize");
        return Response.ok(systemConfigService.optimizeDatabase()).build();
    }

    /**
     * Forcer la déconnexion globale
     */
    @POST
    @Path("/auth/logout-all")
    @RolesAllowed({"SUPER_ADMIN"})
    @Operation(summary = "Forcer la déconnexion de tous les utilisateurs")
    public Response forceGlobalLogout() {
        log.info("POST /api/system/auth/logout-all");
        return Response.ok(systemConfigService.forceGlobalLogout()).build();
    }

    /**
     * Nettoyer les sessions expirées
     */
    @POST
    @Path("/sessions/cleanup")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Nettoyer les sessions expirées")
    public Response cleanupSessions() {
        log.info("POST /api/system/sessions/cleanup");
        return Response.ok(systemConfigService.cleanupSessions()).build();
    }

    /**
     * Nettoyer les anciens logs
     */
    @POST
    @Path("/logs/cleanup")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Nettoyer les anciens logs selon la politique de rétention")
    public Response cleanOldLogs() {
        log.info("POST /api/system/logs/cleanup");
        return Response.ok(systemConfigService.cleanOldLogs()).build();
    }

    /**
     * Purger les données expirées
     */
    @POST
    @Path("/data/purge")
    @RolesAllowed({"SUPER_ADMIN"})
    @Operation(summary = "Purger les données expirées (RGPD)")
    public Response purgeExpiredData() {
        log.info("POST /api/system/data/purge");
        return Response.ok(systemConfigService.purgeExpiredData()).build();
    }

    /**
     * Analyser les performances de la base de données
     */
    @POST
    @Path("/performance/analyze")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Analyser les performances du système")
    public Response analyzePerformance() {
        log.info("POST /api/system/performance/analyze");
        return Response.ok(systemConfigService.analyzePerformance()).build();
    }

    /**
     * Créer une sauvegarde
     */
    @POST
    @Path("/backup/create")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Créer une sauvegarde du système")
    public Response createBackup() {
        log.info("POST /api/system/backup/create");
        return Response.ok(systemConfigService.createBackup()).build();
    }

    /**
     * Planifier une maintenance
     */
    @POST
    @Path("/maintenance/schedule")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Planifier une maintenance")
    public Response scheduleMaintenance(@QueryParam("scheduledAt") String scheduledAt, @QueryParam("reason") String reason) {
        log.info("POST /api/system/maintenance/schedule");
        return Response.ok(systemConfigService.scheduleMaintenance(scheduledAt, reason)).build();
    }

    /**
     * Activer la maintenance d'urgence
     */
    @POST
    @Path("/maintenance/emergency")
    @RolesAllowed({"SUPER_ADMIN"})
    @Operation(summary = "Activer le mode maintenance d'urgence")
    public Response emergencyMaintenance() {
        log.info("POST /api/system/maintenance/emergency");
        return Response.ok(systemConfigService.emergencyMaintenance()).build();
    }

    /**
     * Vérifier les mises à jour
     */
    @GET
    @Path("/updates/check")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Vérifier les mises à jour disponibles")
    public Response checkUpdates() {
        log.info("GET /api/system/updates/check");
        return Response.ok(systemConfigService.checkUpdates()).build();
    }

    /**
     * Exporter les logs récents
     */
    @GET
    @Path("/logs/export")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Exporter les logs des dernières 24h")
    public Response exportLogs() {
        log.info("GET /api/system/logs/export");
        return Response.ok(systemConfigService.exportLogs()).build();
    }

    /**
     * Générer un rapport d'utilisation
     */
    @GET
    @Path("/reports/usage")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN"})
    @Operation(summary = "Générer un rapport d'utilisation du système")
    public Response generateUsageReport() {
        log.info("GET /api/system/reports/usage");
        return Response.ok(systemConfigService.generateUsageReport()).build();
    }

    /**
     * Générer un rapport d'audit
     */
    @GET
    @Path("/audit/report")
    @RolesAllowed({"SUPER_ADMIN", "ADMIN", "MODERATEUR"})
    @Operation(summary = "Générer un rapport d'audit")
    public Response generateAuditReport() {
        log.info("GET /api/system/audit/report");
        return Response.ok(systemConfigService.generateAuditReport()).build();
    }

    /**
     * Export RGPD
     */
    @POST
    @Path("/gdpr/export")
    @RolesAllowed({"SUPER_ADMIN"})
    @Operation(summary = "Initier un export RGPD des données utilisateurs")
    public Response exportGDPRData() {
        log.info("POST /api/system/gdpr/export");
        return Response.ok(systemConfigService.exportGDPRData()).build();
    }
}
