# Affichage Optimisé des Événements Récurrents

## Problème résolu

Avant cette mise à jour, lorsqu'un événement récurrent générait plusieurs occurrences (ex: culte tous les dimanches), **toutes les occurrences** étaient affichées dans la liste des événements, créant de la redondance :

```
❌ Ancien comportement:
- Culte du Dimanche - 04/01/2026
- Culte du Dimanche - 11/01/2026
- Culte du Dimanche - 18/01/2026
- Culte du Dimanche - 25/01/2026
- ... (des dizaines d'occurrences)
```

## Solution implémentée

Le système affiche maintenant **uniquement la prochaine occurrence** de chaque événement récurrent :

```
✅ Nouveau comportement:
- Culte du Dimanche - 04/01/2026 (prochaine occurrence)
- Réunion de Prière - 08/01/2026 (prochaine occurrence)
- Conférence Annuelle - 15/02/2026 (événement unique)
```

## Comment ça fonctionne

### Méthode principale : `getNextOccurrences()`

Cette méthode statique dans le modèle `Event` :

1. **Récupère** tous les événements à venir ou en cours
2. **Groupe** les événements par titre et église
3. **Filtre** pour ne garder que la prochaine occurrence de chaque groupe
4. **Retourne** une collection optimisée

### Logique de filtrage

Pour chaque groupe d'événements ayant le même titre :

- **Si plusieurs occurrences** (événement récurrent) :
  - Cherche la prochaine instance (non récurrente) la plus proche
  - Si aucune instance future, affiche l'événement parent

- **Si une seule occurrence** (événement unique) :
  - L'affiche tel quel

## Pages concernées

### 1. Page d'accueil (`/`)

```php
// PublicController@home
$allNextEvents = Event::getNextOccurrences();
$nextEvent = $upcomingEventsAll->first(); // Premier à venir
$upcomingEvents = $upcomingEventsAll->skip(1)->take(5); // 5 suivants
$ongoingEvents = $allNextEvents->where('status', 'ongoing'); // En cours
```

**Affiche** :
- 1 événement principal (prochain à venir)
- 5 événements à venir
- Événements en cours

### 2. Page des événements (`/events`)

```php
// PublicController@events
$events = Event::getNextOccurrences();
```

**Affiche** :
- Toutes les prochaines occurrences de tous les événements
- Sans duplication

## Exemples pratiques

### Cas 1 : Événement hebdomadaire (Culte)

**Occurrences dans la base :**
- 04/01/2026, 11/01/2026, 18/01/2026, 25/01/2026... (10 occurrences)

**Affichage public :**
- ✅ Uniquement : 04/01/2026 (prochaine)

### Cas 2 : Événement bi-hebdomadaire (Réunion de prière)

**Occurrences dans la base :**
- Mercredi 08/01, Vendredi 10/01, Mercredi 15/01, Vendredi 17/01...

**Affichage public :**
- ✅ Uniquement : Mercredi 08/01 (prochaine)

### Cas 3 : Événement unique (Conférence)

**Occurrences dans la base :**
- 15/02/2026 (une seule)

**Affichage public :**
- ✅ 15/02/2026

### Cas 4 : Événement mensuel (Culte de Jeûne)

**Occurrences dans la base :**
- 01/02/2026, 01/03/2026, 01/04/2026...

**Affichage public :**
- ✅ Uniquement : 01/02/2026 (prochaine)

## Avantages

### Pour les visiteurs
- ✅ **Liste claire** sans répétitions
- ✅ **Rapidité** de consultation
- ✅ **Pertinence** : seul le prochain événement compte

### Pour les administrateurs
- ✅ **Aucun changement** dans l'administration
- ✅ **Génération automatique** toujours active
- ✅ **Flexibilité** : possibilité de modifier une occurrence spécifique

### Performance
- ✅ **Optimisé** : filtrage en mémoire après requête
- ✅ **Efficace** : une seule requête SQL
- ✅ **Scalable** : fonctionne avec des centaines d'événements

## Code technique

### Dans le modèle Event

```php
public static function getNextOccurrences()
{
    $now = \Carbon\Carbon::now();

    // Récupérer tous les événements à venir
    $allEvents = self::with('church')
        ->where('status', '!=', 'cancelled')
        ->where(function($q) use ($now) {
            $q->where('event_date', '>=', $now->toDateString())
              ->orWhere('status', 'ongoing');
        })
        ->orderBy('event_date', 'asc')
        ->get();

    // Grouper par titre et église
    $grouped = $allEvents->groupBy(function($event) {
        return $event->title . '_' . $event->church_id;
    });

    // Pour chaque groupe, ne garder que la prochaine occurrence
    $nextEvents = collect();

    foreach ($grouped as $key => $events) {
        if ($events->count() > 1) {
            // Événement récurrent : prendre la prochaine instance
            $nextOccurrence = $events
                ->where('is_recurring', false)
                ->where('event_date', '>=', $now->toDateString())
                ->sortBy('event_date')
                ->first();

            if ($nextOccurrence) {
                $nextEvents->push($nextOccurrence);
            }
        } else {
            // Événement unique
            $nextEvents->push($events->first());
        }
    }

    return $nextEvents->sortBy('event_date')->values();
}
```

### Dans le contrôleur

```php
// Au lieu de :
$events = Event::where('status', '!=', 'cancelled')->get();

// Utiliser :
$events = Event::getNextOccurrences();
```

## Notes importantes

1. **Événements passés** : Ne sont jamais affichés (filtrés par date)
2. **Événements annulés** : Exclus automatiquement (`status != cancelled`)
3. **Événements en cours** : Inclus dans le résultat
4. **Ordre** : Trié par date croissante (du plus proche au plus lointain)

## Impact sur l'administration

**Aucun changement** dans l'interface d'administration :
- Les administrateurs voient toujours **toutes les occurrences**
- Peuvent modifier/supprimer chaque occurrence individuellement
- Le filtrage s'applique **uniquement** sur le site public

## Support

Pour toute question sur ce système, contactez l'équipe de développement.
