DrawController.java

package com.archiweb.api;

import com.archiweb.model.Draw;
import com.archiweb.model.User;
import com.archiweb.model.Win;
import com.archiweb.repository.DrawRepository;
import com.archiweb.repository.UserRepository;
import com.archiweb.repository.WinRepository;
import com.archiweb.service.EmailService;
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.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

@RestController
@RequestMapping("/api/draw")
@Tag(
        name = "Tirages",
        description = """
        Module de gestion des **tirages au sort** du jeu concours Thé Tip Top.  
        Ce contrôleur permet :
        - D’effectuer le **tirage final** pour désigner le grand gagnant.  
        - De **consulter le résultat** du tirage final après son exécution.  
        Le tirage est unique et ne peut être réalisé qu’une seule fois.
        """
)
public class DrawController {

    private final WinRepository winRepository;
    private final UserRepository userRepository;
    private final DrawRepository drawRepository;
    private final EmailService emailService;

    public DrawController(WinRepository winRepository,
                          UserRepository userRepository,
                          DrawRepository drawRepository,
                          EmailService emailService) {
        this.winRepository = winRepository;
        this.userRepository = userRepository;
        this.drawRepository = drawRepository;
        this.emailService = emailService;
    }

    // =========================================================
    // 1️⃣ Effectuer le tirage final
    // =========================================================
    @Operation(
            summary = "Effectuer le tirage final du jeu concours",
            description = """
            Sélectionne automatiquement un **gagnant parmi tous les participants** du jeu concours.  
            Le tirage final ne peut être effectué **qu’une seule fois**.  
            Si un tirage de type `FINAL` existe déjà, l’appel est rejeté.
            """,
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Tirage final effectué avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = """
                                            {
                                              "status": "success",
                                              "message": "Tirage final effectué avec succès.",
                                              "winner": {
                                                "id": 8,
                                                "username": "lea.dupont",
                                                "email": "lea.dupont@example.com"
                                              },
                                              "drawType": "FINAL",
                                              "createdAt": "2025-10-27T15:30:00"
                                            }
                                            """
                                    )
                            )
                    ),
                    @ApiResponse(
                            responseCode = "400",
                            description = "Aucun participant",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = "{ \"error\": \"Aucun participant, tirage impossible.\" }"
                                    )
                            )
                    ),
                    @ApiResponse(
                            responseCode = "409",
                            description = "Tirage déjà effectué",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = "{ \"error\": \"Le tirage final a déjà été effectué.\" }"
                                    )
                            )
                    )
            }
    )
    @PostMapping("/final")
    public ResponseEntity<?> performFinalDraw() {
        if (drawRepository.existsByType("FINAL")) {
            Map<String, String> error = new HashMap<>();
            error.put("error", "Le tirage final a déjà été effectué.");
            return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
        }

        List<Win> allWins = winRepository.findAll();
        if (allWins.isEmpty()) {
            Map<String, String> error = new HashMap<>();
            error.put("error", "Aucun participant, tirage impossible.");
            return ResponseEntity.badRequest().body(error);
        }

        Random random = new Random();
        Win selectedWin = allWins.get(random.nextInt(allWins.size()));
        User winner = selectedWin.getUser();

        Draw draw = new Draw();
        draw.setType("FINAL");
        draw.setWinner(winner);
        draw.setCreatedAt(LocalDateTime.now());
        drawRepository.save(draw);

        // Envoyer un email au gagnant
        try {
            String emailContent = generateFinalDrawWinnerEmail(winner);
            emailService.sendEmailHtml(
                winner.getEmail(),
                "🎉 Félicitations ! Vous avez gagné le tirage final !",
                emailContent
            );
        } catch (Exception e) {
            // Logger l'erreur mais ne pas faire échouer le tirage
            System.err.println("Erreur lors de l'envoi de l'email au gagnant: " + e.getMessage());
        }

        return ResponseEntity.ok(
                String.format(
                        "{\"status\":\"success\",\"message\":\"Tirage final effectué avec succès.\",\"winner\":{\"id\":%d,\"username\":\"%s\",\"email\":\"%s\"},\"drawType\":\"FINAL\",\"createdAt\":\"%s\"}",
                        winner.getId(), winner.getUsername(), winner.getEmail(), LocalDateTime.now()
                )
        );
    }

    // =========================================================
    // 2️⃣ Obtenir le gagnant du tirage final
    // =========================================================
    @Operation(
            summary = "Obtenir le gagnant du tirage final",
            description = """
            Retourne les informations du **gagnant désigné lors du tirage final**.  
            Si aucun tirage de type `FINAL` n’a encore été réalisé, un message d’erreur est renvoyé.
            """,
            responses = {
                    @ApiResponse(
                            responseCode = "200",
                            description = "Gagnant récupéré avec succès",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = """
                                            {
                                              "status": "success",
                                              "winner": {
                                                "id": 8,
                                                "username": "lea.dupont",
                                                "email": "lea.dupont@example.com"
                                              },
                                              "drawType": "FINAL",
                                              "drawDate": "2025-10-27T15:30:00"
                                            }
                                            """
                                    )
                            )
                    ),
                    @ApiResponse(
                            responseCode = "404",
                            description = "Aucun tirage final encore effectué",
                            content = @Content(
                                    mediaType = "application/json",
                                    examples = @ExampleObject(
                                            value = "{ \"error\": \"Aucun tirage final n'a encore été effectué.\" }"
                                    )
                            )
                    )
            }
    )
    @GetMapping("/winner")
    public ResponseEntity<?> getFinalWinner() {
        Optional<Draw> draw = drawRepository.findByType("FINAL");
        if (draw.isEmpty()) {
            Map<String, String> error = new HashMap<>();
            error.put("error", "Aucun tirage final n'a encore été effectué.");
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
        }

        User winner = draw.get().getWinner();
        return ResponseEntity.ok(
                String.format(
                        "{\"status\":\"success\",\"winner\":{\"id\":%d,\"username\":\"%s\",\"email\":\"%s\"},\"drawType\":\"FINAL\",\"drawDate\":\"%s\"}",
                        winner.getId(), winner.getUsername(), winner.getEmail(), draw.get().getCreatedAt()
                )
        );
    }

    // =========================================================
    // 3️⃣ Générer l'email HTML pour le gagnant du tirage final
    // =========================================================
    private String generateFinalDrawWinnerEmail(User winner) {
        String drawDate = LocalDateTime.now().format(java.time.format.DateTimeFormatter.ofPattern("dd MMMM yyyy 'à' HH:mm", java.util.Locale.FRENCH));
        
        return String.format("""
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>🎉 Vous avez gagné le tirage final !</title>
</head>
<body style="margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background-color: #f5f5f5;">
  <table width="100%%" cellpadding="0" cellspacing="0" style="background-color: #f5f5f5; padding: 40px 20px;">
    <tr>
      <td align="center">
        <table width="600" cellpadding="0" cellspacing="0" style="background-color: #ffffff; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 20px rgba(0,0,0,0.1);">
          <!-- Header avec gradient doré -->
          <tr>
            <td style="background: linear-gradient(135deg, #FFD700 0%%, #FFA500 100%%); padding: 50px 30px; text-align: center;">
              <div style="font-size: 80px; margin-bottom: 20px;">🏆</div>
              <h1 style="color: #ffffff; margin: 0; font-size: 36px; font-weight: 700; text-shadow: 0 2px 4px rgba(0,0,0,0.3);">
                🎉 FÉLICITATIONS ! 🎉
              </h1>
              <p style="color: #ffffff; margin: 15px 0 0 0; font-size: 20px; opacity: 0.95; font-weight: 600;">
                Vous avez gagné le TIRAGE FINAL !
              </p>
            </td>
          </tr>
          
          <!-- Contenu principal -->
          <tr>
            <td style="padding: 40px 30px;">
              <div style="text-align: center; margin-bottom: 30px;">
                <h2 style="color: #FF6B00; margin: 0 0 20px 0; font-size: 28px; font-weight: 700;">
                  🎁 Grand Gagnant du Jeu Concours Thé Tip Top
                </h2>
                <p style="color: #333; font-size: 18px; line-height: 1.6; margin: 0 0 10px 0;">
                  Félicitations <strong style="color: #FF6B00;">%s</strong> !
                </p>
                <p style="color: #666; font-size: 16px; line-height: 1.6; margin: 0;">
                  Vous avez été sélectionné(e) lors du tirage final effectué le <strong>%s</strong>.
                </p>
              </div>
              
              <!-- Badge de victoire -->
              <div style="text-align: center; margin: 30px 0; padding: 25px; background: linear-gradient(135deg, #FFD700 0%%, #FFA500 100%%); border-radius: 12px; box-shadow: 0 4px 15px rgba(255, 215, 0, 0.4);">
                <div style="font-size: 50px; margin-bottom: 10px;">✨</div>
                <p style="color: #ffffff; font-size: 20px; font-weight: 700; margin: 0; text-shadow: 0 2px 4px rgba(0,0,0,0.2);">
                  VOUS ÊTES LE GRAND GAGNANT !
                </p>
              </div>
              
              <!-- Informations importantes -->
              <div style="background-color: #FFF3E0; border-left: 4px solid #FF9800; padding: 25px; border-radius: 8px; margin: 30px 0;">
                <h3 style="color: #E65100; margin: 0 0 15px 0; font-size: 20px; font-weight: 600;">
                  📋 Prochaines étapes
                </h3>
                <ul style="color: #666; font-size: 16px; line-height: 2; margin: 0; padding-left: 25px;">
                  <li>Vous serez contacté(e) sous <strong>48 heures</strong> par notre équipe</li>
                  <li>Nous vous expliquerons les modalités de réception de votre lot</li>
                  <li>Vous devrez confirmer vos coordonnées pour la livraison</li>
                  <li>Votre lot sera expédié ou disponible en boutique selon votre choix</li>
                </ul>
              </div>
              
              <!-- Contact -->
              <div style="background-color: #E8F5E9; border-left: 4px solid #4CAF50; padding: 20px; border-radius: 8px; margin: 30px 0;">
                <h3 style="color: #2E7D32; margin: 0 0 15px 0; font-size: 18px; font-weight: 600;">
                  📞 Besoin d'aide ?
                </h3>
                <p style="color: #333; font-size: 16px; margin: 0; line-height: 1.6;">
                  Pour toute question, n'hésitez pas à nous contacter :<br>
                  <strong>Email :</strong> service@thetiptop.com<br>
                  <strong>Téléphone :</strong> 01 23 45 67 89
                </p>
              </div>
              
              <!-- Message de félicitations -->
              <div style="text-align: center; margin: 30px 0; padding: 20px; background-color: #f9f9f9; border-radius: 12px;">
                <p style="color: #333; font-size: 18px; font-weight: 600; margin: 0; line-height: 1.6;">
                  Merci d'avoir participé au jeu concours Thé Tip Top !<br>
                  <span style="color: #FF6B00; font-size: 24px;">🎊 Félicitations encore une fois ! 🎊</span>
                </p>
              </div>
            </td>
          </tr>
          
          <!-- Footer -->
          <tr>
            <td style="background-color: #2E7D32; padding: 30px; text-align: center;">
              <p style="color: #ffffff; margin: 0 0 10px 0; font-size: 16px; font-weight: 600;">
                Thé Tip Top - Jeu Concours
              </p>
              <p style="color: #ffffff; margin: 0; font-size: 14px; opacity: 0.9;">
                Merci de votre participation et félicitations pour votre victoire !
              </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
  </table>
</body>
</html>
""", winner.getUsername() != null ? winner.getUsername() : winner.getEmail(), drawDate);
    }
}