StatsController.java

package com.archiweb.api;

import com.archiweb.dto.StatsResponse;
import com.archiweb.service.StatsService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/api/stats")
@Tag(
        name = "Statistiques",
        description = """
        Regroupe toutes les statistiques globales du jeu concours :
        - Codes : utilisés, restants et expirés
        - Participations : totales, réclamées, non réclamées
        - Gains : répartition par type de lot
        - Données démographiques : âge moyen, consentement, etc.
        """
)
public class StatsController {

    private final StatsService statsService;

    public StatsController(StatsService statsService) {
        this.statsService = statsService;
    }

    // ==============================
    // 1️⃣ - Statistiques globales filtrées
    // ==============================
    @Operation(
            summary = "Obtenir les statistiques globales filtrées",
            description = """
            Permet de récupérer les statistiques du jeu en filtrant selon :
            - lot (type de lot, ex: INFUSEUR)
            - boutique (nom ou ID du point de vente)
            - période (format libre : '2025-01', 'S1-2025', etc.)
            """,
            responses = {
                    @ApiResponse(responseCode = "200", description = "Statistiques récupérées avec succès",
                            content = @Content(
                                    schema = @Schema(implementation = StatsResponse.class),
                                    examples = @ExampleObject(value = """
                                            {
                                              "totalCodes": 500000,
                                              "codesUtilises": 200000,
                                              "codesNonUtilises": 300000,
                                              "codesExpires": 5000,
                                              "totalParticipations": 150000,
                                              "participationsReclamees": 140000,
                                              "participationsNonReclamees": 10000,
                                              "repartitionLots": {
                                                "INFUSEUR": 300000,
                                                "DETOX_100G": 100000,
                                                "SIGNATURE_100G": 50000
                                              }
                                            }
                                            """)
                            )
                    ),
                    @ApiResponse(responseCode = "400", description = "Paramètres invalides"),
                    @ApiResponse(responseCode = "401", description = "Jeton JWT manquant ou invalide")
            }
    )
    @GetMapping
    public StatsResponse getStats(
            @Parameter(description = "Type de lot à filtrer (ex: INFUSEUR, DETOX_100G)")
            @RequestParam(required = false) String lot,
            @Parameter(description = "Nom de la boutique ou identifiant du point de vente")
            @RequestParam(required = false) String boutique,
            @Parameter(description = "Période (format libre : '2025-01', 'S1-2025', etc.)")
            @RequestParam(required = false) String periode) {
        return statsService.getStats(lot, boutique, periode);
    }

    // ==============================
    // 2️⃣ - Statistiques globales simples
    // ==============================
    @Operation(
            summary = "Obtenir les statistiques globales (sans filtres)",
            description = "Renvoie les statistiques générales du jeu sans appliquer de filtres.",
            responses = {
                    @ApiResponse(responseCode = "200", description = "Statistiques globales récupérées avec succès")
            }
    )
    @GetMapping("/global")
    public StatsResponse getGlobalStats() {
        return statsService.getStats();
    }

    // ==============================
    // 3️⃣ - Statistiques démographiques
    // ==============================
    @Operation(
            summary = "Obtenir les statistiques démographiques",
            description = "Renvoie des informations démographiques sur les participants : âge moyen, consentements, etc.",
            responses = {
                    @ApiResponse(responseCode = "200", description = "Statistiques démographiques récupérées avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(value = """
                                            {
                                              "totalUsers": 12450,
                                              "averageAge": 31.7,
                                              "consentGiven": 9870
                                            }
                                            """)
                            )
                    )
            }
    )
    @GetMapping("/demographics")
    public ResponseEntity<Map<String, Object>> getDemographics() {
        Map<String, Object> data = statsService.getDemographicStats();
        return ResponseEntity.ok(data);
    }

    // ==============================
    // 4️⃣ - Statistiques des gains
    // ==============================
    @Operation(
            summary = "Obtenir les statistiques des gains",
            description = "Retourne la répartition du nombre de lots gagnés par type (INFUSEUR, DETOX_100G, etc.).",
            responses = {
                    @ApiResponse(responseCode = "200", description = "Statistiques des gains récupérées avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(value = """
                                            {
                                              "INFUSEUR": 300000,
                                              "DETOX_100G": 100000,
                                              "SIGNATURE_100G": 50000,
                                              "COFFRET_39": 30000,
                                              "COFFRET_69": 20000
                                            }
                                            """)
                            )
                    )
            }
    )
    @GetMapping("/wins")
    public ResponseEntity<Map<String, Long>> getWinsStats() {
        Map<String, Long> stats = statsService.getWinsStats();
        return ResponseEntity.ok(stats);
    }

    // ==============================
    // 5️⃣ - Statistiques des codes
    // ==============================
    @Operation(
            summary = "Obtenir les statistiques des codes",
            description = "Renvoie la répartition des codes selon leur état : utilisés, restants et expirés.",
            responses = {
                    @ApiResponse(responseCode = "200", description = "Statistiques des codes récupérées avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(value = """
                                            {
                                              "totalCodes": 500000,
                                              "usedCodes": 200000,
                                              "unusedCodes": 295000,
                                              "expiredCodes": 5000
                                            }
                                            """)
                            )
                    )
            }
    )
    @GetMapping("/codes")
    public ResponseEntity<Map<String, Long>> getCodesStats() {
        Map<String, Long> stats = statsService.getCodesStats();
        return ResponseEntity.ok(stats);
    }
}