# Système d'Événements Récurrents

## Vue d'ensemble

Le système permet de créer des événements récurrents (cultes hebdomadaires, réunions mensuelles, etc.) qui se génèrent **automatiquement à la sauvegarde** de l'événement parent.

## Configuration d'un événement récurrent

### Dans l'interface d'administration

Lors de la création/modification d'un événement:

1. Cochez **"Événement récurrent"**
2. Sélectionnez le **type de récurrence**:
   - **Quotidienne** : Répète chaque jour
   - **Hebdomadaire** : Répète chaque semaine
   - **Mensuelle** : Répète chaque mois
   - **Annuelle** : Répète chaque année

3. Définissez l'**intervalle** (optionnel):
   - Ex: `1` = chaque semaine, `2` = toutes les 2 semaines

4. Pour les événements **hebdomadaires**, sélectionnez les jours:
   - Ex: `["sunday"]` pour tous les dimanches
   - Ex: `["wednesday", "friday", "sunday"]` pour plusieurs jours

5. Définissez la **date de fin** (optionnel):
   - Laissez vide pour une récurrence indéfinie
   - Ou spécifiez une date de fin

### Exemples de configuration

#### Culte du dimanche
```
- Titre: Culte du Dimanche
- Date: 2025-01-05 (premier dimanche)
- Heure: 09:00
- Récurrent: Oui
- Type: Hebdomadaire
- Intervalle: 1
- Jours: ["sunday"]
- Date de fin: (vide ou date future)
```

#### Réunions de prière (Mercredi et Vendredi)
```
- Titre: Réunion de Prière
- Date: 2025-01-08 (premier mercredi)
- Heure: 19:00
- Récurrent: Oui
- Type: Hebdomadaire
- Intervalle: 1
- Jours: ["wednesday", "friday"]
```

## Génération automatique

### Comment ça fonctionne

Le système utilise un **Observer Laravel** qui se déclenche automatiquement à chaque sauvegarde d'un événement récurrent.

**Quand vous créez ou modifiez un événement récurrent**, le système:
1. Détecte automatiquement que c'est un événement récurrent
2. Calcule la date de la prochaine occurrence
3. Crée immédiatement la prochaine instance de l'événement
4. Et ce, **sans aucune intervention manuelle**

**Pas besoin de cron job, pas besoin de commande artisan** - tout est automatique!

### Commande manuelle (optionnelle)

Si vous souhaitez générer plusieurs occurrences d'un coup pour une période donnée, vous pouvez utiliser:

```bash
php artisan events:generate-recurring
```

Options:
- `--days=30` : Générer pour les 30 prochains jours (par défaut)
- `--days=60` : Générer pour les 60 prochains jours
- `--days=90` : Générer pour les 90 prochains jours

Cette commande est utile pour:
- Générer plusieurs mois d'événements à l'avance
- Repeupler le calendrier si nécessaire
- Tester le système de récurrence

## Comportement du système

### Génération intelligente

- ✅ **Automatique à la sauvegarde** : Dès que vous enregistrez un événement récurrent, la prochaine occurrence est créée
- ✅ **Évite les doublons** : Ne créera pas d'événement si un existe déjà pour cette date
- ✅ **Respect de la date de fin** : S'arrête automatiquement à la date de fin spécifiée
- ✅ **Gestion des jours spécifiques** : Pour les événements hebdomadaires avec plusieurs jours
- ✅ **Statut hérité** : Les nouvelles occurrences héritent du statut de l'événement parent
- ✅ **Génération en chaîne** : Chaque nouvelle occurrence créée peut elle-même déclencher la création de la suivante

### Événements générés

Les événements générés:
- Ont la même configuration que l'événement parent (titre, description, lieu, etc.)
- Ont `is_recurring = false` (ce sont des instances, pas des parents)
- Peuvent être modifiés/supprimés individuellement sans affecter l'événement parent
- Apparaissent normalement dans la liste des événements
- Se créent automatiquement au moment de la sauvegarde de l'événement parent

## Gestion dans l'admin

### Modifier un événement récurrent

**Option 1 : Modifier l'événement parent**
- Les changements affecteront les **futures** générations
- Les occurrences déjà générées ne sont **pas modifiées**

**Option 2 : Modifier une occurrence spécifique**
- Modifiez l'événement individuel généré
- Ne modifie **que cette occurrence**

### Arrêter la récurrence

1. Éditez l'événement parent
2. Définissez une **date de fin de récurrence**
3. Sauvegardez
4. Les générations futures s'arrêteront automatiquement

### Supprimer toutes les occurrences futures

1. Éditez l'événement parent
2. Décochez **"Événement récurrent"**
3. OU définissez la date de fin à aujourd'hui

## Surveillance

### Vérifier les événements générés

```bash
# Voir les événements des 30 prochains jours
php artisan tinker
>>> \App\Models\Event::where('event_date', '>=', now())->where('event_date', '<=', now()->addDays(30))->count()
```

### Logs

La commande génère des logs lors de l'exécution:
```
✅ Generation complete!
  - Events generated: 12
  - Events skipped (already exist): 3
```

## Bonnes pratiques

1. **Configurez une fois** : Créez l'événement récurrent avec tous les détails
2. **Vérification immédiate** : Après sauvegarde, vérifiez que la prochaine occurrence a été créée
3. **Date de fin** : Utilisez-la pour les événements saisonniers
4. **Génération en masse** : Utilisez la commande `events:generate-recurring` pour créer plusieurs mois à l'avance si souhaité
5. **Vérification** : Consultez régulièrement le calendrier des événements

## Résolution de problèmes

### Aucun événement n'est généré automatiquement

- Vérifiez que l'événement parent a `is_recurring = true`
- Vérifiez que l'événement parent a bien un `recurrence_type` (daily, weekly, monthly, yearly)
- Vérifiez que la `recurrence_end_date` n'est pas déjà dépassée
- Vérifiez que l'Observer est bien enregistré dans `AppServiceProvider`
- Consultez les logs: `storage/logs/laravel.log`

### Événements dupliqués

- Le système vérifie automatiquement les doublons
- Si des doublons apparaissent, vérifiez la configuration de l'événement parent
- Vérifiez qu'il n'y a pas d'événements créés manuellement avec le même titre et la même date

### L'Observer ne se déclenche pas

- Vérifiez que `Event::observe(EventObserver::class);` est bien dans `AppServiceProvider::boot()`
- Effacez le cache de configuration: `php artisan config:clear`
- Effacez le cache de l'application: `php artisan cache:clear`

## Support

Pour toute question, contactez l'équipe de développement.
