CodeGenerator.java

package com.archiweb.init;

import com.archiweb.model.Code;
import com.archiweb.model.PrizeType;
import com.archiweb.repository.CodeRepository;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;

@Component
public class CodeGenerator implements CommandLineRunner {

    private final CodeRepository repo;

    public CodeGenerator(CodeRepository repo) {
        this.repo = repo;
    }

    // Génère un code alphanumérique de 10 caractères
    private String generateRandomCode() {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 10; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        return sb.toString();
    }

    @Override
    public void run(String... args) {
        if (repo.count() > 0) {
            return;
        }

        long total = 500_000L;
        Map<PrizeType, Double> distribution = Map.of(
                PrizeType.INFUSEUR, 0.60,
                PrizeType.DETOX_100G, 0.20,
                PrizeType.SIGNATURE_100G, 0.10,
                PrizeType.COFFRET_39, 0.06,
                PrizeType.COFFRET_69, 0.04
        );

        LocalDateTime expiresAt = LocalDateTime.now().plusDays(60);

        List<Code> codes = new ArrayList<>();
        Set<String> usedCodes = new HashSet<>();

        for (Map.Entry<PrizeType, Double> entry : distribution.entrySet()) {
            PrizeType type = entry.getKey();
            long count = Math.round(total * entry.getValue());

            for (int i = 0; i < count; i++) {

                String generated;
                do {
                    generated = generateRandomCode();
                } while (usedCodes.contains(generated)); // éviter les doublons

                usedCodes.add(generated);

                Code c = new Code();
                c.setValeur(generated);         // nouveau format aléatoire ✨
                c.setPrizeType(type);           // gain non visible dans le code
                c.setExpiresAt(expiresAt);
                c.setUsed(false);

                codes.add(c);
            }
        }

        // Mélanger tous les codes
        Collections.shuffle(codes);

        // Insertion batch
        int batchSize = 10_000;
        for (int i = 0; i < codes.size(); i += batchSize) {
            int end = Math.min(i + batchSize, codes.size());
            repo.saveAll(codes.subList(i, end));
            System.out.printf("✅ Batch %d / %d inséré%n", (i / batchSize) + 1, (codes.size() / batchSize));
        }

    }
}