# Mobile API Documentation - Room WebSocket Functionality

This document provides comprehensive API documentation for mobile clients to implement real-time room functionality using WebSockets.

## API Endpoints

### 1. Join Room
**POST** `/api/v1/user/join-room`

**Request Body:**
```json
{
    "room_id": "123456789"
}
```

**Response:**
```json
{
    "status": "success",
    "message": "joined in room",
    "welcome_message": "Welcome to the room! 🎉 We're glad to have you here.",
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com",
        "user_profile": {
            // user profile data
        }
    },
    "join_room": {
        "id": 1,
        "room": 1,
        "room_id": "123456789",
        "user_id": 1,
        "is_host": 0,
        "created_at": "2024-01-01T12:00:00.000000Z"
    },
    "room": {
        "id": 1,
        "room_id": "123456789",
        "room_name": "My Room",
        "room_description": "Room description",
        "room_type": "public",
        "room_image": "https://example.com/image.jpg"
    },
    "websocket_channel": "room.123456789",
    "websocket_events": {
        "user_joined": "user.joined.room",
        "user_left": "user.left.room"
    }
}
```

### 2. Leave Room
**POST** `/api/v1/user/leave-room`

**Request Body:**
```json
{
    "room_id": "123456789"
}
```

**Response:**
```json
{
    "status": "success",
    "message": "left the room",
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    "room": {
        "id": 1,
        "room_id": "123456789",
        "room_name": "My Room"
    },
    "websocket_channel": "room.123456789",
    "websocket_events": {
        "user_joined": "user.joined.room",
        "user_left": "user.left.room"
    }
}
```

### 3. Get Room Users
**GET** `/api/v1/user/get-joined-room-users/{room_id}`

**Response:**
```json
{
    "status": "success",
    "message": "Joined room users",
    "room_join_info": {
        "id": 1,
        "room_id": "123456789",
        "room_name": "My Room",
        "join_room_users": [
            {
                "id": 1,
                "joined_at": "2024-01-01T12:00:00.000000Z",
                "is_host": 1,
                "user": {
                    "id": 1,
                    "name": "John Doe",
                    "email": "john@example.com",
                    "profile": {
                        // user profile data
                    }
                }
            }
        ]
    },
    "websocket_channel": "room.123456789",
    "websocket_events": {
        "user_joined": "user.joined.room",
        "user_left": "user.left.room"
    }
}
```

### 4. Get WebSocket Configuration
**GET** `/api/v1/user/websocket-config`

**Response:**
```json
{
    "status": "success",
    "websocket_config": {
        "broadcaster": "pusher",
        "key": "your-pusher-key",
        "cluster": "mt1",
        "force_tls": true,
        "events": {
            "user_joined_room": "user.joined.room",
            "user_left_room": "user.left.room"
        }
    }
}
```

## WebSocket Implementation

### Channel Naming Convention
- **Format:** `room.{room_id}`
- **Example:** Room ID `123456789` → Channel `room.123456789`

### Event Types

#### 1. User Joined Room Event
**Event Name:** `user.joined.room`

**Data Structure:**
```json
{
    "type": "user_joined",
    "join_room": {
        "id": 1,
        "joined_at": "2024-01-01T12:00:00.000000Z",
        "is_host": false
    },
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    "room": {
        "id": 1,
        "room_id": "123456789",
        "room_name": "My Room"
    },
    "message": "John Doe joined the room",
    "timestamp": "2024-01-01T12:00:00.000000Z"
}
```

#### 2. User Left Room Event
**Event Name:** `user.left.room`

**Data Structure:**
```json
{
    "type": "user_left",
    "join_room": {
        "id": 1,
        "left_at": "2024-01-01T12:00:00.000000Z",
        "is_host": false
    },
    "user": {
        "id": 1,
        "name": "John Doe",
        "email": "john@example.com"
    },
    "room": {
        "id": 1,
        "room_id": "123456789",
        "room_name": "My Room"
    },
    "message": "John Doe left the room",
    "timestamp": "2024-01-01T12:00:00.000000Z"
}
```

## Mobile Implementation Examples

### Flutter/Dart Example
```dart
import 'package:pusher_client/pusher_client.dart';

class RoomWebSocket {
  PusherClient? pusher;
  Channel? channel;
  
  Future<void> connectToRoom(String roomId) async {
    // Get WebSocket config from API
    final config = await getWebSocketConfig();
    
    pusher = PusherClient(
      config['key'],
      PusherOptions(
        cluster: config['cluster'],
        encrypted: true,
      ),
    );
    
    channel = pusher!.subscribe('room.$roomId');
    
    // Listen for user joined events
    channel!.bind('user.joined.room', (event) {
      final data = jsonDecode(event.data!);
      print('${data['user']['name']} joined the room');
      // Update UI
    });
    
    // Listen for user left events
    channel!.bind('user.left.room', (event) {
      final data = jsonDecode(event.data!);
      print('${data['user']['name']} left the room');
      // Update UI
    });
  }
  
  void disconnect() {
    channel?.unsubscribe();
    pusher?.disconnect();
  }
}
```

### React Native Example
```javascript
import Pusher from 'pusher-js/react-native';

class RoomWebSocket {
  constructor() {
    this.pusher = null;
    this.channel = null;
  }
  
  async connectToRoom(roomId, config) {
    this.pusher = new Pusher(config.key, {
      cluster: config.cluster,
      forceTLS: true,
    });
    
    this.channel = this.pusher.subscribe(`room.${roomId}`);
    
    this.channel.bind('user.joined.room', (data) => {
      console.log(`${data.user.name} joined the room`);
      // Update UI
    });
    
    this.channel.bind('user.left.room', (data) => {
      console.log(`${data.user.name} left the room`);
      // Update UI
    });
  }
  
  disconnect() {
    if (this.channel) {
      this.pusher.unsubscribe(`room.${roomId}`);
    }
    if (this.pusher) {
      this.pusher.disconnect();
    }
  }
}
```

### Swift (iOS) Example
```swift
import PusherSwift

class RoomWebSocket {
    var pusher: Pusher?
    var channel: PusherChannel?
    
    func connectToRoom(roomId: String, config: [String: Any]) {
        let options = PusherClientOptions(
            host: .cluster(config["cluster"] as! String)
        )
        
        pusher = Pusher(
            key: config["key"] as! String,
            options: options
        )
        
        channel = pusher?.subscribe(channelName: "room.\(roomId)")
        
        channel?.bind(eventName: "user.joined.room") { [weak self] (event: PusherEvent) in
            if let data = event.data {
                // Parse JSON and update UI
                print("User joined room")
            }
        }
        
        channel?.bind(eventName: "user.left.room") { [weak self] (event: PusherEvent) in
            if let data = event.data {
                // Parse JSON and update UI
                print("User left room")
            }
        }
        
        pusher?.connect()
    }
    
    func disconnect() {
        channel?.unsubscribe()
        pusher?.disconnect()
    }
}
```

### Kotlin (Android) Example
```kotlin
import com.pusher.client.Pusher
import com.pusher.client.channel.Channel

class RoomWebSocket {
    private var pusher: Pusher? = null
    private var channel: Channel? = null
    
    fun connectToRoom(roomId: String, config: Map<String, Any>) {
        val pusherOptions = PusherOptions()
            .setCluster(config["cluster"] as String)
        
        pusher = Pusher(config["key"] as String, pusherOptions)
        
        channel = pusher?.subscribe("room.$roomId")
        
        channel?.bind("user.joined.room") { event ->
            // Parse JSON and update UI
            println("User joined room")
        }
        
        channel?.bind("user.left.room") { event ->
            // Parse JSON and update UI
            println("User left room")
        }
        
        pusher?.connect()
    }
    
    fun disconnect() {
        channel?.unsubscribe()
        pusher?.disconnect()
    }
}
```

## Error Handling

### Common Error Responses

```json
{
    "status": "error",
    "message": "room not found"
}
```

```json
{
    "status": "error",
    "message": "user already joined"
}
```

```json
{
    "status": "error",
    "message": "User not in this room"
}
```

## Best Practices

1. **Connection Management:**
   - Always disconnect WebSocket connections when leaving rooms
   - Implement reconnection logic for network issues
   - Handle connection state changes

2. **Error Handling:**
   - Implement proper error handling for API calls
   - Handle WebSocket connection failures
   - Provide user feedback for errors

3. **Performance:**
   - Only subscribe to channels when needed
   - Unsubscribe from channels when leaving rooms
   - Implement proper cleanup in app lifecycle

4. **Security:**
   - Always authenticate users before allowing room access
   - Validate room IDs on the server side
   - Implement rate limiting for join/leave operations

## Testing

### Test WebSocket Events
1. Join a room using the API
2. Subscribe to the room's WebSocket channel
3. Have another user join the same room
4. Verify the `user.joined.room` event is received
5. Have the user leave the room
6. Verify the `user.left.room` event is received

### Test API Endpoints
Use tools like Postman or curl to test all API endpoints:

```bash
# Join room
curl -X POST /api/v1/user/join-room \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"room_id": "123456789"}'

# Leave room
curl -X POST /api/v1/user/leave-room \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"room_id": "123456789"}'
``` 