EmailController.java

package com.archiweb.api;
import java.util.Map;
import com.archiweb.model.User;
import com.archiweb.service.EmailService;
import com.archiweb.repository.UserRepository;
import io.swagger.v3.oas.annotations.Operation;
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 lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api/email")
@RequiredArgsConstructor
@Tag(
        name = "Emailing",
        description = """
        Module de gestion des campagnes d’e-mailing et du respect des consentements RGPD.  
        Ce contrôleur permet :
        - L’envoi d’un e-mail à des destinataires spécifiques ou à tous les abonnés consentants.  
        - La récupération de la liste complète des abonnés ayant accepté de recevoir des communications.  
        - L’envoi groupé automatisé via un service d’e-mail externe (EmailService).
        """
)
public class EmailController {

    private final EmailService emailService;
    private final UserRepository userRepository;

    // =========================================================
    // 1️⃣ Envoi d’un email
    // =========================================================
    @Operation(
            summary = "Envoyer un email",
            description = """
            Permet d’envoyer un e-mail à une liste spécifique de destinataires, ou à **tous les utilisateurs ayant donné leur consentement** (`consentGiven = true`).  
            Si aucun destinataire n’est fourni, le système enverra automatiquement l’e-mail à tous les abonnés consentants enregistrés.
            """,
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    description = "Contenu et paramètres de l’e-mail à envoyer",
                    required = true,
                    content = @Content(
                            schema = @Schema(implementation = EmailRequest.class),
                            examples = @ExampleObject(
                                    value = """
                                    {
                                      "subject": "Nouveau jeu concours Thé Tip Top !",
                                      "message": "Découvrez nos nouveaux lots et participez dès aujourd’hui sur notre site.",
                                      "recipients": [
                                        "client1@example.com",
                                        "client2@example.com"
                                      ]
                                    }
                                    """
                            )
                    )
            ),
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Email(s) envoyé(s) avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = "{ \"message\": \"Emails envoyés avec succès à 42 destinataires.\" }"
                                    )
                            )
                    ),
                    @ApiResponse(
                            responseCode = "400",
                            description = "Sujet, message ou destinataires manquants",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = "{ \"error\": \"Sujet et message obligatoires.\" }"
                                    )
                            )
                    )
            }
    )
    @PostMapping("/send")
    public ResponseEntity<?> sendEmail(@RequestBody EmailRequest request) {
        if (request.getSubject() == null || request.getMessage() == null) {
            return ResponseEntity.badRequest().body("Sujet et message obligatoires.");
        }

        List<String> recipients = request.getRecipients();

        // Si aucun destinataire n'est fourni, envoi à tous les abonnés consentants
        if (recipients == null || recipients.isEmpty()) {
            recipients = userRepository.findAll().stream()
                    .filter(User::isConsentGiven)
                    .map(User::getEmail)
                    .toList();
        }

        if (recipients.isEmpty()) {
            return ResponseEntity.badRequest()
                    .body("Aucun destinataire trouvé (aucun abonné avec consentement).");
        }

        // Log pour déboguer

        // Utiliser sendBulkEmailHtml si isHtml est true, sinon sendBulkEmail (texte)
        int sentCount;
        if (Boolean.TRUE.equals(request.getIsHtml())) {
            sentCount = emailService.sendBulkEmailHtml(request.getSubject(), request.getMessage(), recipients);
        } else {
            sentCount = emailService.sendBulkEmail(request.getSubject(), request.getMessage(), recipients);
        }
        
        return ResponseEntity.ok("Emails envoyés avec succès à " + sentCount + " destinataires.");
    }

    // =========================================================
    // 2️⃣ Récupération des abonnés
    // =========================================================
    @Operation(
            summary = "Lister les abonnés",
            description = """
            Renvoie la **liste complète des utilisateurs ayant donné leur consentement** pour recevoir des e-mails promotionnels ou informatifs.  
            Utile pour le suivi RGPD et les statistiques de campagne.
            """,
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Liste des abonnés récupérée avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = """
                                            [
                                              {
                                                "id": 1,
                                                "email": "client@example.com",
                                                "consentGiven": true
                                              }
                                            ]
                                            """
                                    )
                            )
                    )
            }
    )
    @GetMapping("/subscribers")
    public ResponseEntity<List<User>> getSubscribers() {
        List<User> subscribers = userRepository.findAll().stream()
                .filter(User::isConsentGiven)
                .toList();
        return ResponseEntity.ok(subscribers);
    }

    // =========================================================
    // Classe interne pour la requête d'envoi d'e-mail
    // =========================================================
    @Data
    public static class EmailRequest {
        @Schema(description = "Sujet de l'e-mail", example = "Jeu concours Thé Tip Top")
        private String subject;

        @Schema(description = "Corps du message à envoyer (peut être du HTML si isHtml=true)", example = "Participez dès maintenant et gagnez un coffret exclusif.")
        private String message;

        @Schema(description = "Liste des adresses e-mail des destinataires. Si vide, envoi à tous les abonnés consentants.")
        private List<String> recipients;

        @Schema(description = "Indique si le message est du HTML (défaut: false)", example = "true")
        private Boolean isHtml = false;
    }
}