# API Messagerie Instantanée - Guide Développeur

## Vue d'ensemble

Cette documentation technique présente l'implémentation du système de messagerie instantanée, incluant les APIs WebSocket et REST, l'architecture des composants React et les fonctions utilitaires.

## API WebSocket

### Connexion

**URL de connexion :**

```javascript
// Développement
ws://localhost:8000/ws/chat/{userId}/

// Production
wss://[domaine]/ws/chat/{userId}/
```

### Messages WebSocket

#### Messages entrants (serveur → client)

```javascript
// Liste des conversations
{
  "type": "conversations_list",
  "conversations": [...]
}

// Nouveau message reçu
{
  "type": "new_message",
  "message": {
    "id": 123,
    "conversation_id": 456,
    "sender_id": 789,
    "content": "Contenu du message",
    "timestamp": "2024-01-01T12:00:00Z"
  }
}

// Utilisateur en train d'écrire
{
  "type": "typing_start",
  "conversation_id": 456,
  "user_id": 789
}

// Utilisateur a arrêté d'écrire
{
  "type": "typing_stop",
  "conversation_id": 456,
  "user_id": 789
}
```

#### Messages sortants (client → serveur)

```javascript
// Envoyer un message
{
  "type": "chat_message",
  "conversation_id": 456,
  "message": "Contenu du message"
}

// Signaler début de frappe
{
  "type": "typing_start",
  "conversation_id": 456
}

// Signaler fin de frappe
{
  "type": "typing_stop",
  "conversation_id": 456
}

// Marquer comme lu
{
  "type": "mark_as_read",
  "conversation_id": 456
}

// Rejoindre une conversation
{
  "type": "join_conversation",
  "conversation_id": 456
}
```

## API REST

### Endpoints disponibles

```javascript
// Récupérer les conversations
GET /api/messagerie/conversations/{userId}/
Response: Array<Conversation>

// Récupérer les messages d'une conversation
GET /api/messagerie/messages/{conversationId}/
Response: Array<Message>

// Rechercher des destinataires
GET /api/messagerie/search/{establishmentId}/?q={query}
Response: Array<User>

// Créer une conversation
POST /api/messagerie/conversations/create/
Body: { "participants": [userId1, userId2] }
Response: Conversation

// Envoyer un email (séparé de la messagerie instantanée)
POST /api/email/send/
Body: { "recipients": [...], "subject": "...", "content": "..." }
```

## Composants React

### InstantChat

**Props :**

```javascript
{
  userProfileId: number,     // ID de l'utilisateur connecté
  establishmentId: number    // ID de l'établissement
}
```

**États principaux :**

- `conversations` : Liste des conversations
- `selectedConversation` : Conversation active
- `messages` : Messages de la conversation active
- `searchQuery` : Terme de recherche
- `searchResults` : Résultats de recherche de contacts

### useWebSocket Hook

**Paramètres :**

```javascript
useWebSocket(
  userProfileId, // ID utilisateur
  onMessage, // Callback pour messages reçus
  onConnectionChange // Callback changement de connexion
);
```

**Valeurs retournées :**

```javascript
{
  isConnected: boolean,
  connectionStatus: string,
  sendChatMessage: (conversationId, content) => boolean,
  sendTypingStart: (conversationId) => void,
  sendTypingStop: (conversationId) => void,
  markAsRead: (conversationId) => void,
  joinConversation: (conversationId) => void,
  reconnect: () => void
}
```

## Actions Redux/State

### messagerieAction.js

```javascript
// Récupérer les conversations
fetchConversations(userId): Promise<Array<Conversation>>

// Récupérer les messages
fetchMessages(conversationId): Promise<Array<Message>>

// Rechercher des destinataires
searchMessagerieRecipients(establishmentId, query): Promise<Array<User>>

// Créer une conversation
createConversation(participants): Promise<Conversation>
```

### emailAction.js

```javascript
// Envoyer un email
sendEmail(recipients, subject, content, csrfToken): Promise<Response>

// Rechercher des destinataires email
searchEmailRecipients(establishmentId, query): Promise<Array<User>>
```

## Modèles de Données

### Conversation

```javascript
{
  conversation_id: number,
  participants: Array<User>,
  last_message: Message,
  created_at: string,
  updated_at: string
}
```

### Message

```javascript
{
  id: number,
  conversation_id: number,
  sender_id: number,
  content: string,
  timestamp: string,
  is_read: boolean
}
```

### User

```javascript
{
  id: number,
  first_name: string,
  last_name: string,
  email: string,
  role: string
}
```

## Gestion des Erreurs

### WebSocket

```javascript
// Reconnexion automatique
const reconnectWebSocket = () => {
  setConnectionStatus('reconnecting');
  // Logique de reconnexion avec backoff exponentiel
};

// Gestion des erreurs de connexion
wsRef.current.onerror = (error) => {
  logger.error('Erreur WebSocket:', error);
  setIsConnected(false);
};
```

### API REST

```javascript
// Wrapper avec gestion d'erreur
const apiCall = async (url, options) => {
  try {
    const response = await fetch(url, options);
    if (!response.ok) {
      throw new Error(`Erreur ${response.status}`);
    }
    return await response.json();
  } catch (error) {
    logger.error('Erreur API:', error);
    throw error;
  }
};
```

## Configuration des Tests

### Jest Setup

```javascript
// jest.setup.js
global.WebSocket = class MockWebSocket {
  // Mock complet du WebSocket pour les tests
};

global.fetch = jest.fn(() =>
  Promise.resolve({
    ok: true,
    json: () => Promise.resolve([]),
  })
);
```

### Tests des Composants

```javascript
// Exemple de test
test('renders InstantChat component', async () => {
  await act(async () => {
    render(<InstantChat userProfileId={1} establishmentId={123} />);
  });

  expect(screen.getByText('Messages')).toBeInTheDocument();
});
```

## Intégration Backend

### Consumer Django

```python
# consumers.py
class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        # Logique de connexion

    async def chat_message(self, event):
        # Traitement des messages
```

### URLs Configuration

```python
# routing.py
websocket_urlpatterns = [
    re_path(r'ws/chat/(?P<user_id>\w+)/$', ChatConsumer.as_asgi()),
]
```

## Optimisations

### Performance

- Pagination des messages anciens (load on scroll)
- Debounce pour la recherche de contacts (300ms)
- Memoization des composants avec React.memo
- Lazy loading des conversations

### UX

- Reconnexion automatique avec feedback visuel
- Sauvegarde locale des messages en cours de frappe
- Indicateurs de livraison des messages
- Scrolling automatique vers les nouveaux messages
