# Widgets Sociaux - Architecture Modulaire

Architecture de composants réutilisables pour les posts sociaux avec support d'images et vidéos.

## 📐 Architecture

### 🔹 Widgets Atomiques (Niveau 1)

Les plus petits composants réutilisables dans toute l'application.

#### `SocialActionButton`
**Bouton d'action tout petit et uniforme**
- Taille par défaut: 22px
- Supporte tooltip
- Animation scale: 0.85
- Couleur personnalisable

```dart
SocialActionButton(
  icon: Icons.favorite_rounded,
  onTap: () => handleLike(),
  color: Colors.red,
  tooltip: 'J\'aime',
)
```

#### `SocialActionButtonWithCount`
**Bouton d'action avec compteur**
- Affichage du nombre (1K, 1M formaté)
- Support état actif/inactif
- Couleur différente si actif

```dart
SocialActionButtonWithCount(
  icon: Icons.favorite_rounded,
  count: 245,
  onTap: () => handleLike(),
  isActive: true,
  activeColor: Colors.red,
)
```

#### `SocialBadge`
**Badge réutilisable générique**
- Icône optionnelle
- Couleurs personnalisables
- Taille de police ajustable
- Padding personnalisable

```dart
SocialBadge(
  label: 'Nouveau',
  icon: Icons.fiber_new,
  fontSize: 11,
)
```

#### `VerifiedBadge`
**Badge de compte vérifié**
- Icône verified avec tooltip
- Taille personnalisable

```dart
VerifiedBadge(size: 16)
```

#### `CategoryBadge`
**Badge de catégorie**
- Couleur secondaire
- Icône optionnelle

```dart
CategoryBadge(
  category: 'Sport',
  icon: Icons.sports_soccer,
)
```

#### `StatusBadge`
**Badge de statut dynamique**
- Couleurs automatiques selon le statut
  - "nouveau" → primaryContainer
  - "tendance" → errorContainer
  - "populaire" → tertiaryContainer

```dart
StatusBadge(
  status: 'tendance',
  icon: Icons.trending_up,
)
```

#### `MediaCountBadge`
**Badge de nombre de médias**
- Pour images/vidéos
- Affichage sur fond noir semi-transparent
- Icône différente selon le type

```dart
MediaCountBadge(
  count: 5,
  isVideo: false,
)
```

### 🔹 Widgets de Médias (Niveau 2)

Composants spécialisés pour la gestion des médias.

#### `PostMedia` (Model)
**Modèle de données pour un média**
```dart
class PostMedia {
  final String url;
  final MediaType type; // image ou video
  final String? thumbnailUrl;
  final Duration? duration;
}
```

#### `PostMediaViewer`
**Affichage de médias avec dispositions multiples**
- 1 média: Aspect ratio 1:1
- 2 médias: Côte à côte
- 3 médias: 1 grand + 2 petits
- 4+ médias: Grille 2x2 avec compteur "+N"

**Fonctionnalités:**
- Hero animation
- Loading progressif
- Gestion d'erreurs
- Tap pour plein écran
- Badge de durée pour vidéos

```dart
PostMediaViewer(
  medias: [
    PostMedia(url: 'image1.jpg', type: MediaType.image),
    PostMedia(url: 'video1.mp4', type: MediaType.video, duration: Duration(minutes: 2, seconds: 30)),
  ],
  postId: post.id,
  onTap: () => handleMediaTap(),
)
```

#### `MediaPicker`
**Sélecteur de médias pour création de post**
- Sélection depuis galerie (multi)
- Capture photo depuis caméra
- Sélection vidéo
- Limite: 10 médias max (personnalisable)
- Prévisualisation avec bouton supprimer
- Indicateur vidéo sur thumbnails

**Fonctionnalités:**
- Compteur médias sélectionnés
- Boutons désactivés si limite atteinte
- Grille horizontale scrollable
- Suppression individuelle

```dart
MediaPicker(
  onMediasChanged: (medias) {
    setState(() => selectedMedias = medias);
  },
  maxMedias: 10,
  initialMedias: [],
)
```

### 🔹 Dialogues et Composants Complexes (Niveau 3)

#### `CreatePostDialog`
**Dialogue de création de post avec médias**

**Fonctionnalités:**
- Avatar et nom utilisateur
- Champ texte (3-8 lignes, max 500 caractères)
- MediaPicker intégré
- Validation formulaire
- État de chargement pendant création
- Compteur caractères
- Visibilité (Public par défaut)
- **Compression automatique** des images avant upload
- **Upload progressif** avec indicateur de progression
- **Nettoyage automatique** des fichiers temporaires

**Processus d'upload en 3 étapes:**
1. Compression des images (0-50%)
2. Upload des médias (50-100%)
3. Création du post

**Présentation:**
- Modal bottom sheet
- Auto-focus sur le champ texte
- Padding adapté au clavier
- Actions: Annuler / Publier
- Barre de progression avec statut textuel

```dart
await CreatePostDialog.show(
  context: context,
  onPostCreated: (content, medias) async {
    await createPost(content, medias);
  },
  userName: 'Jean Dupont',
  userAvatarUrl: 'avatar.jpg',
);
```

#### `EditPostDialog`
**Dialogue d'édition de post existant**

**Fonctionnalités:**
- Pré-remplissage avec contenu existant
- Détection automatique des changements
- MediaPicker pour modifier les médias
- Validation formulaire
- Bouton "Enregistrer" désactivé si aucun changement
- État de chargement pendant mise à jour

**Présentation:**
- Modal bottom sheet
- Auto-focus sur le champ texte
- Icône d'édition dans l'en-tête
- Actions: Annuler / Enregistrer

```dart
await EditPostDialog.show(
  context: context,
  post: existingPost,
  onPostUpdated: (content, medias) async {
    await updatePost(existingPost.id, content, medias);
  },
);
```

#### `FullscreenVideoPlayer`
**Lecteur vidéo plein écran avec contrôles**

**Fonctionnalités:**
- Lecture automatique au démarrage
- Orientation paysage forcée
- Mode immersif (barre système cachée)
- Contrôles tactiles :
  - Tap pour afficher/masquer contrôles
  - Play/Pause
  - Reculer de 10s
  - Avancer de 10s
- Barre de progression interactive (scrubbing)
- Affichage durée actuelle / totale
- Hero animation pour transition fluide

**Présentation:**
- Fond noir
- Header avec bouton fermer et titre
- Contrôles centraux (reculer/play/avancer)
- Footer avec barre de progression
- Gradient overlay sur header/footer

```dart
await FullscreenVideoPlayer.show(
  context: context,
  videoUrl: 'https://example.com/video.mp4',
  heroTag: 'post_media_123_0',
  title: 'Ma vidéo',
);
```

#### `SocialCardRefactored`
**Card modulaire de post social**

**Composants internes:**
- `_PostHeader`: Avatar gradient, nom, badge vérifié, timestamp, menu
- `_UserAvatar`: Avatar avec bordure gradient
- `_PostTimestamp`: Formatage relatif (Il y a X min/h/j)
- `_PostMenu`: PopupMenu (Modifier, Supprimer)
- `_PostActions`: Like, Comment, Share, Bookmark
- `_PostStats`: Nombre de likes
- `_PostContent`: Texte enrichi (hashtags #, mentions @)
- `_CommentsLink`: Lien vers commentaires

**Fonctionnalités:**
- Support médias via PostMediaViewer
- Hashtags et mentions cliquables (couleur primaire)
- "Voir plus/Voir moins" pour contenu long (>150 caractères)
- Badge de catégorie optionnel
- Badge vérifié optionnel
- AnimatedCard avec elevation

```dart
SocialCardRefactored(
  post: post,
  onLike: () => handleLike(),
  onComment: () => handleComment(),
  onShare: () => handleShare(),
  onDeletePost: () => handleDelete(),
  onEditPost: () => handleEdit(),
  showVerifiedBadge: true,
  showCategory: true,
  category: 'Sport',
)
```

## 🔧 Services (lib/data/services/)

### `ImageCompressionService`
**Service de compression d'images avant upload**

**Configurations prédéfinies:**
- `CompressionConfig.post` : 85% qualité, 1920x1920px
- `CompressionConfig.thumbnail` : 70% qualité, 400x400px
- `CompressionConfig.story` : 90% qualité, 1080x1920px
- `CompressionConfig.avatar` : 80% qualité, 500x500px

**Fonctionnalités:**
- Compression avec qualité ajustable (0-100)
- Redimensionnement automatique
- Support formats: JPEG, PNG, WebP
- Compression parallèle pour plusieurs images
- Callback de progression
- Statistiques de réduction de taille
- Nettoyage automatique des fichiers temporaires

**Utilisation:**

```dart
final compressionService = ImageCompressionService();

// Compression d'une image
final compressed = await compressionService.compressImage(
  imageFile,
  config: CompressionConfig.post,
);

// Compression multiple avec progression
final compressedList = await compressionService.compressMultipleImages(
  imageFiles,
  config: CompressionConfig.thumbnail,
  onProgress: (processed, total) {
    print('Compression: $processed/$total');
  },
);

// Créer un thumbnail
final thumbnail = await compressionService.createThumbnail(imageFile);

// Nettoyer les fichiers temporaires
await compressionService.cleanupTempFiles();
```

**Logs (si EnvConfig.enableDetailedLogs = true):**
```
[ImageCompression] Compression de: photo.jpg
[ImageCompression] Taille originale: 4.2 MB
[ImageCompression] Taille compressée: 1.8 MB
[ImageCompression] Réduction: 57.1%
```

### `MediaUploadService`
**Service d'upload de médias vers le backend**

**Fonctionnalités:**
- Upload d'images et vidéos
- Upload parallèle de plusieurs médias
- Callback de progression
- Génération automatique de thumbnails pour vidéos
- Support vidéos locales et réseau
- Suppression de médias

**Modèle de résultat:**
```dart
class MediaUploadResult {
  final String url;           // URL du média uploadé
  final String? thumbnailUrl; // URL du thumbnail (vidéo)
  final String type;          // 'image' ou 'video'
  final Duration? duration;   // Durée (vidéo seulement)
}
```

**Utilisation:**

```dart
final uploadService = MediaUploadService(http.Client());

// Upload d'un média
final result = await uploadService.uploadMedia(imageFile);
print('URL: ${result.url}');

// Upload multiple avec progression
final results = await uploadService.uploadMultipleMedias(
  mediaFiles,
  onProgress: (uploaded, total) {
    print('Upload: $uploaded/$total');
  },
);

// Générer thumbnail pour vidéo
final thumbnailUrl = await uploadService.generateVideoThumbnail(videoUrl);

// Supprimer un média
await uploadService.deleteMedia(mediaUrl);
```

**Configuration:**
Le endpoint d'upload est configuré dans `EnvConfig.mediaUploadEndpoint`.

## 📦 Utilisation

### Import Simple
```dart
import 'package:afterwork/presentation/widgets/social/social_widgets.dart';
```

Ceci importe tous les widgets nécessaires :
- Boutons d'action
- Badges
- Media picker
- Post media viewer
- Create post dialog
- Social card

### Exemple Complet

```dart
// 1. Créer un post avec compression et upload automatiques
await CreatePostDialog.show(
  context: context,
  onPostCreated: (content, medias) async {
    // Les médias sont déjà compressés et uploadés par le dialogue
    await apiService.createPost(
      content: content,
      mediaFiles: medias,
    );
  },
  userName: currentUser.name,
  userAvatarUrl: currentUser.avatar,
);

// 2. Créer un post manuellement avec services
final compressionService = ImageCompressionService();
final uploadService = MediaUploadService(http.Client());

// Compresser les images
final compressedMedias = await compressionService.compressMultipleImages(
  selectedMedias,
  config: CompressionConfig.post,
  onProgress: (processed, total) {
    print('Compression: $processed/$total');
  },
);

// Uploader les médias
final uploadResults = await uploadService.uploadMultipleMedias(
  compressedMedias,
  onProgress: (uploaded, total) {
    print('Upload: $uploaded/$total');
  },
);

// Créer le post avec les URLs
await apiService.createPost(
  content: contentController.text,
  mediaUrls: uploadResults.map((r) => r.url).toList(),
);

// Nettoyer les fichiers temporaires
await compressionService.cleanupTempFiles();

// 3. Afficher un post avec médias
SocialCardRefactored(
  post: SocialPost(
    id: '123',
    content: 'Super soirée avec les amis ! #afterwork @john',
    imageUrl: '', // Géré par medias maintenant
    likesCount: 42,
    commentsCount: 5,
    sharesCount: 2,
    isLikedByCurrentUser: false,
    // ...
  ),
  medias: [
    PostMedia(
      url: 'https://example.com/photo1.jpg',
      type: MediaType.image,
    ),
    PostMedia(
      url: 'https://example.com/video1.mp4',
      type: MediaType.video,
      thumbnailUrl: 'https://example.com/video1_thumb.jpg',
      duration: Duration(minutes: 2, seconds: 30),
    ),
  ],
  onLike: () {
    setState(() {
      post = post.copyWith(
        isLikedByCurrentUser: !post.isLikedByCurrentUser,
        likesCount: post.isLikedByCurrentUser
          ? post.likesCount - 1
          : post.likesCount + 1,
      );
    });
  },
  onComment: () {
    Navigator.push(/* CommentsScreen */);
  },
  onEditPost: () async {
    await EditPostDialog.show(
      context: context,
      post: post,
      onPostUpdated: (content, medias) async {
        await apiService.updatePost(post.id, content, medias);
      },
    );
  },
  onDeletePost: () async {
    await apiService.deletePost(post.id);
  },
  showVerifiedBadge: user.isVerified,
  showCategory: true,
  category: post.category,
);

// 4. Afficher une vidéo en plein écran
GestureDetector(
  onTap: () {
    FullscreenVideoPlayer.show(
      context: context,
      videoUrl: 'https://example.com/video.mp4',
      heroTag: 'post_media_${post.id}_0',
      title: 'Ma vidéo',
    );
  },
  child: Stack(
    children: [
      Image.network(videoThumbnail),
      Center(
        child: Icon(Icons.play_circle_outline, size: 64),
      ),
    ],
  ),
);
```

## 🎨 Principes de Design

### Uniformité
- Tous les boutons icônes: 20-22px
- Tous les badges: fontSize 10-11px
- Spacing: DesignSystem constants (4, 8, 12, 16px)
- Border radius: DesignSystem (4, 10, 16px)

### Réutilisabilité
- Chaque composant fait UNE chose
- Props claires et typées
- Valeurs par défaut sensées
- Documentation inline

### Performances
- Widgets const quand possible
- Keys pour listes
- Lazy loading des images
- AnimatedCard pour hover effects

### Accessibilité
- Tooltips sur tous les boutons
- Couleurs avec contraste suffisant
- Tailles tactiles minimales respectées (44x44)

## 🔧 Personnalisation

### Thème
Tous les widgets utilisent le ThemeData du contexte :
- `theme.colorScheme.primary`
- `theme.colorScheme.onSurface`
- `theme.textTheme.bodyMedium`

### DesignSystem
Les constantes sont centralisées :
- `DesignSystem.spacingSm` (8px)
- `DesignSystem.spacingMd` (12px)
- `DesignSystem.spacingLg` (16px)
- `DesignSystem.radiusSm` (4px)
- `DesignSystem.radiusMd` (10px)
- `DesignSystem.radiusLg` (16px)

## 📝 Statut des Fonctionnalités

### ✅ Complété

- [x] **Support de plusieurs médias par post** - PostMediaViewer supporte 1-10+ médias avec dispositions adaptatives
- [x] **Upload des médias vers le backend** - MediaUploadService avec progression et support image/vidéo
- [x] **Lecteur vidéo en plein écran** - FullscreenVideoPlayer avec contrôles complets
- [x] **Édition de post avec médias** - EditPostDialog avec détection de changements
- [x] **Compression d'images avant upload** - ImageCompressionService avec 4 configs prédéfinies
- [x] **Architecture modulaire** - Widgets atomiques, réutilisables et bien documentés
- [x] **Animations et interactions** - Like, bookmark, hero transitions, scale effects
- [x] **Hashtags et mentions cliquables** - Parsing et styling automatiques
- [x] **Progress tracking** - Indicateurs de progression pour compression et upload

### 🚧 À Venir

- [ ] **Stories avec médias** - Système de stories éphémères (24h) avec images/vidéos
- [ ] **Filtres sur les photos** - Filtres Instagram-style pour édition d'images
- [ ] **GIF support** - Support des GIFs animés dans les posts
- [ ] **Commentaires imbriqués** - Système de réponses aux commentaires
- [ ] **Réactions étendues** - Plus de réactions au-delà du simple like (❤️ 😂 😮 😢 😡)
- [ ] **Partage vers stories** - Partager un post dans sa story
- [ ] **Brouillons** - Sauvegarder des posts en brouillon
- [ ] **Planification** - Programmer la publication d'un post

### 📊 Métriques

- **13 widgets** créés (atomiques + composites)
- **2 services** (compression + upload)
- **5 types de badges** réutilisables
- **4 layouts** pour affichage médias (1, 2, 3, 4+)
- **3 étapes** de processus d'upload (compression, upload, création)
- **10 médias max** par post (configurable)
