# API Reference

Complete API reference for the Milton Health Coach FCM Client SDK.

## Table of Contents

1. [MiltonAsyncClient](#miltonasyncclient)
2. [Configuration](#configuration)
3. [Methods](#methods)
4. [Types and Interfaces](#types-and-interfaces)
5. [Error Handling](#error-handling)
6. [Events and Callbacks](#events-and-callbacks)

## MiltonAsyncClient

The main SDK class that provides asynchronous request processing with intelligent polling and push notification support.

### Constructor

```javascript
new MiltonAsyncClient(config)
```

**Parameters:**
- `config` (MiltonSDKConfig): Configuration object

**Example:**
```javascript
import { MiltonAsyncClient } from 'milton-fcm-client-sdk';

const client = new MiltonAsyncClient({
  baseUrl: 'https://api.milton.com',
  apiKey: 'your-api-key',
  enablePushNotifications: true
});
```

## Configuration

### MiltonSDKConfig

Main configuration object for the SDK.

```javascript
{
  baseUrl: string,              // Required: Milton API base URL
  apiKey: string,               // Required: Your API key
  timeout?: number,             // Optional: Request timeout in ms (default: 30000)
  enablePushNotifications?: boolean, // Optional: Enable FCM push notifications (default: true)
  clientIdConfig?: ClientIdConfig,   // Optional: Client ID configuration
  pollingConfig?: PollingConfig,     // Optional: Polling configuration
  offlineConfig?: OfflineConfig      // Optional: Offline handling configuration
}
```

**Required Parameters:**
- `baseUrl`: Your Milton API server URL (must include protocol)
- `apiKey`: Your authentication API key

**FCM Requirement:**
- `enablePushNotifications` defaults to `true` and **MUST NOT** be set to `false`
- Firebase Cloud Messaging must be properly configured before using the SDK
- See [FCM Setup Checklist](FCM_SETUP_CHECKLIST.md) for setup verification

**Validation:**
- `baseUrl` must be a valid URL format
- `apiKey` must be a non-empty string
- `enablePushNotifications` must be `true` (FCM is mandatory)
- All optional parameters have validation ranges (see [Configuration Guide](CONFIGURATION_GUIDE.md))

### ClientIdConfig

Configuration for automatic client ID generation and management.

```javascript
{
  autoGenerate?: boolean,       // Enable auto-generation (default: true)
  prefix?: string,              // Custom prefix (default: 'milton')
  includeDeviceInfo?: boolean,  // Include device info (default: true)
  includePlatform?: boolean,    // Include platform (default: true)
  includeAppVersion?: boolean,  // Include app version (default: true)
  customClientId?: string,      // Use custom ID instead of auto-generation
  storageKey?: string           // AsyncStorage key (default: 'milton_client_id')
}
```

**Example:**
```javascript
const clientIdConfig = {
  autoGenerate: true,
  prefix: 'myapp',
  includeDeviceInfo: true,
  includePlatform: true,
  includeAppVersion: true
};
```

### PollingConfig

Configuration for intelligent polling behavior.

```javascript
{
  intervals?: number[],         // Polling intervals in seconds (default: [5, 10, 20, 40, 80, 120])
  maxAttempts?: number,         // Maximum polling attempts (default: 6)
  timeoutMs?: number,          // Polling timeout in ms (default: 30000)
  backgroundIntervals?: number[], // Background polling intervals (default: [30, 60, 120, 300])
  batteryOptimized?: boolean    // Enable battery optimization (default: true)
}
```

**Example:**
```javascript
const pollingConfig = {
  intervals: [5, 10, 20, 40, 80, 120],
  maxAttempts: 6,
  timeoutMs: 45000,
  batteryOptimized: true
};
```

### OfflineConfig

Configuration for offline request handling.

```javascript
{
  enableOfflineQueue?: boolean, // Enable offline request queuing (default: true)
  maxQueueSize?: number,        // Maximum queue size (default: 50)
  retryAttempts?: number,       // Retry attempts for failed requests (default: 3)
  retryDelay?: number,          // Delay between retries in ms (default: 5000)
  storageKey?: string           // AsyncStorage key for persistence (default: 'milton_offline_queue')
}
```

**Example:**
```javascript
const offlineConfig = {
  enableOfflineQueue: true,
  maxQueueSize: 100,
  retryAttempts: 5,
  retryDelay: 3000
};
```

## Methods

### submitUserMessage(request, options?)

Submit a user message for asynchronous processing.

**Parameters:**
- `request` (UserMessageRequest): User message data
- `options` (RequestOptions, optional): Request options and callbacks

**Returns:** `Promise<AsyncRequestResponse>`

**Example:**
```javascript
const response = await client.submitUserMessage({
  orgId: 123,
  userId: 456,
  question: "What should I eat for breakfast?",
  image: "data:image/jpeg;base64,..." // optional
}, {
  onProgress: (status) => {
    console.log('Progress:', status.status);
  },
  onComplete: (result) => {
    console.log('Complete:', result);
  },
  onError: (error) => {
    console.error('Error:', error);
  }
});

console.log('Request ID:', response.request_id);
```

### submitSurvey(request, options?)

Submit survey data for asynchronous processing.

**Parameters:**
- `request` (SurveyRequest): Survey data
- `options` (RequestOptions, optional): Request options and callbacks

**Returns:** `Promise<AsyncRequestResponse>`

**Example:**
```javascript
const response = await client.submitSurvey({
  phone_number: "+1234567890",
  survey: "Mood: good, Energy: 8/10, Sleep: 7.5 hours, Stress: 3/10",
  birthday: "1990-01-01",
  default_timezone: "America/New_York"
}, {
  webhookUrl: "https://your-app.com/webhook",
  onComplete: (result) => {
    console.log('Survey processed:', result);
  }
});
```


### getRequestStatus(requestId)

Get the current status of a request.

**Parameters:**
- `requestId` (string): Request ID to check

**Returns:** `Promise<RequestStatus>`

**Example:**
```javascript
const status = await client.getRequestStatus('request-uuid');
console.log('Status:', status.status);
console.log('Result:', status.result);
```

### cancelRequest(requestId)

Cancel a pending or processing request.

**Parameters:**
- `requestId` (string): Request ID to cancel

**Returns:** `Promise<void>`

**Example:**
```javascript
await client.cancelRequest('request-uuid');
console.log('Request cancelled');
```

### getOfflineQueueStatus()

Get current offline queue and network status.

**Returns:** `OfflineQueueStatus`

**Example:**
```javascript
const status = client.getOfflineQueueStatus();
console.log('Queue length:', status.queueLength);
console.log('Is online:', status.isOnline);
console.log('Active requests:', status.activePollingRequests);
```

### clearOfflineQueue()

Clear all queued offline requests.

**Returns:** `Promise<void>`

**Example:**
```javascript
await client.clearOfflineQueue();
console.log('Offline queue cleared');
```

### getClientId()

Get the current client ID.

**Returns:** `string|null`

**Example:**
```javascript
const clientId = client.getClientId();
console.log('Current client ID:', clientId);
```

### setClientId(clientId)

Set a custom client ID (overrides auto-generated one).

**Parameters:**
- `clientId` (string): Custom client ID (max 100 characters)

**Returns:** `Promise<void>`

**Example:**
```javascript
await client.setClientId('my-custom-client-id');
console.log('Client ID updated');
```

### regenerateClientId()

Clear stored client ID and generate a new one.

**Returns:** `Promise<void>`

**Example:**
```javascript
await client.regenerateClientId();
console.log('New client ID generated:', client.getClientId());
```

### getSDKInfo()

Get comprehensive SDK information including version, configuration, and current status.

**Returns:** `Object`

**Example:**
```javascript
const info = client.getSDKInfo();
console.log('SDK Version:', info.version);
console.log('Client ID:', info.clientId);
console.log('FCM Status:', info.status.fcmToken);
console.log('Active Requests:', info.status.activePollingRequests);
```

**Response Structure:**
```javascript
{
  name: "Milton Health Coach FCM Client SDK",
  version: "1.1.1",
  clientId: "milton-ios-v1.2.3-abc12345-1k2j3h4g",
  configuration: {
    baseUrl: "https://api.milton.com",
    enablePushNotifications: true,
    pollingIntervals: [5, 10, 20, 40, 80, 120],
    maxPollingAttempts: 6,
    batteryOptimized: true,
    offlineQueueEnabled: true,
    maxOfflineQueueSize: 50
  },
  status: {
    fcmToken: "Available",
    isOnline: true,
    isInBackground: false,
    activePollingRequests: 2,
    offlineQueueLength: 0
  }
}
```

### dispose()

Clean up resources and stop all polling. Call this when you're done with the client.

**Returns:** `void`

**Example:**
```javascript
// In React component cleanup
useEffect(() => {
  return () => {
    client.dispose();
  };
}, []);
```

## Types and Interfaces

### UserMessageRequest

```javascript
{
  orgId: number,        // Organization ID
  userId: number,       // User ID
  question: string,     // User question
  image?: string,       // Optional: Base64 encoded image
  sessionId?: string    // Optional: Session identifier
}
```

### SurveyRequest

```javascript
{
  phone_number: string,     // User's phone number
  survey: string,           // Survey response text
  birthday: string,         // User's birthday (YYYY-MM-DD format)
  default_timezone: string  // User's default timezone
}
```



### AsyncRequestResponse

```javascript
{
  request_id: string,                    // Unique request identifier
  status: 'accepted' | 'queued_offline', // Request status
  polling_url?: string,                  // Polling endpoint URL
  estimated_completion_time?: string,    // Estimated completion time
  webhook_url?: string                   // Webhook URL if provided
}
```

### RequestStatus

```javascript
{
  request_id: string,   // Request identifier
  status: string,       // Current status: 'queued', 'processing', 'completed', 'failed', 'cancelled', 'waiting_for_push'
  result?: any,         // Result data (when completed)
  error?: string,       // Error message (when failed)
  created_at: string,   // Creation timestamp
  updated_at: string,   // Last update timestamp
  expires_at: string,   // Expiration timestamp
  message?: string      // Additional status message
}
```

### RequestOptions

```javascript
{
  webhookUrl?: string,                    // Webhook URL for notifications
  clientId?: string,                      // Client identifier
  onProgress?: (status: RequestStatus) => void,  // Progress callback
  onComplete?: (result: any) => void,     // Completion callback
  onError?: (error: Error) => void        // Error callback
}
```

### OfflineQueueStatus

```javascript
{
  queueLength: number,           // Number of queued requests
  isOnline: boolean,             // Network connectivity status
  isInBackground: boolean,       // App background status
  activePollingRequests: number  // Number of active polling requests
}
```

## Error Handling

### Error Types

The SDK can throw various types of errors:

#### Network Errors
- Connection timeout
- Network unavailable
- DNS resolution failure

#### API Errors
- HTTP 400: Bad Request (validation error)
- HTTP 401: Unauthorized (invalid API key)
- HTTP 403: Forbidden (insufficient permissions)
- HTTP 404: Not Found (invalid endpoint or request ID)
- HTTP 410: Gone (request expired)
- HTTP 429: Too Many Requests (rate limited)
- HTTP 503: Service Unavailable (server overloaded)

#### SDK Errors
- Invalid configuration
- Firebase initialization failure
- Storage access error

### Error Handling Examples

```javascript
try {
  const response = await client.submitUserMessage(request, {
    onError: (error) => {
      if (error.message.includes('HTTP 503')) {
        // Server overloaded - retry later
        showRetryDialog();
      } else if (error.message.includes('offline')) {
        // Offline - request queued
        showOfflineMessage();
      } else {
        // Other errors
        showErrorMessage(error.message);
      }
    }
  });
} catch (error) {
  // Handle submission errors
  if (error.message.includes('HTTP 401')) {
    // Invalid API key
    redirectToLogin();
  } else if (error.message.includes('validation')) {
    // Validation error
    showValidationErrors(error.details);
  } else {
    // Generic error
    showGenericError();
  }
}
```

## Events and Callbacks

### Progress Callback

Called during polling to provide status updates.

```javascript
onProgress: (status: RequestStatus) => {
  switch (status.status) {
    case 'queued':
      showMessage('Request queued for processing');
      break;
    case 'processing':
      showMessage('Processing your request...');
      break;
    case 'waiting_for_push':
      showMessage('Waiting for push notification...');
      break;
    case 'queued_offline':
      showMessage('Request queued for when you\'re back online');
      break;
  }
}
```

### Completion Callback

Called when request processing is complete.

```javascript
onComplete: (result: any) => {
  // Handle successful completion
  updateUI(result);
  showSuccessMessage();
  
  // Example result structure for user message:
  // {
  //   response: "Based on your question...",
  //   confidence: 0.95,
  //   suggestions: [...],
  //   metadata: {...}
  // }
}
```

### Error Callback

Called when request processing fails.

```javascript
onError: (error: Error) => {
  console.error('Request failed:', error.message);
  
  // Check error type
  if (error.message.includes('timeout')) {
    showTimeoutError();
  } else if (error.message.includes('validation')) {
    showValidationError();
  } else {
    showGenericError();
  }
}
```

## Advanced Usage

### Custom Polling Configuration

```javascript
const client = new MiltonAsyncClient({
  baseUrl: 'https://api.milton.com',
  apiKey: 'your-api-key',
  pollingConfig: {
    intervals: [5, 10, 20, 40, 80, 120], // Custom intervals up to 120 seconds
    maxAttempts: 6,
    batteryOptimized: true,
    backgroundIntervals: [60, 120, 300] // Longer intervals in background
  }
});
```

### Webhook Integration (Web Clients)

```javascript
const response = await client.submitUserMessage({
  orgId: 123,
  userId: 456,
  question: "Analyze my meal"
}, {
  webhookUrl: 'https://your-app.com/webhook/milton',
  clientId: 'web-client-123'
});
```

### Request Cancellation

```javascript
let currentRequestId = null;

const submitRequest = async () => {
  const response = await client.submitUserMessage(data);
  currentRequestId = response.request_id;
};

const cancelCurrentRequest = async () => {
  if (currentRequestId) {
    await client.cancelRequest(currentRequestId);
    currentRequestId = null;
  }
};
```

### Offline Queue Management

```javascript
// Monitor offline queue
const monitorQueue = () => {
  const status = client.getOfflineQueueStatus();
  
  if (status.queueLength > 0) {
    showQueueStatus(`${status.queueLength} requests queued`);
  }
  
  if (!status.isOnline) {
    showOfflineIndicator();
  }
};

// Clear queue when needed
const clearQueue = async () => {
  await client.clearOfflineQueue();
  showMessage('Queue cleared');
};
```

### Battery Optimization

```javascript
const client = new MiltonAsyncClient({
  baseUrl: 'https://api.milton.com',
  apiKey: 'your-api-key',
  pollingConfig: {
    batteryOptimized: true,
    backgroundIntervals: [30, 60, 120, 300], // Longer intervals in background
    maxAttempts: 4 // Fewer attempts in background
  }
});
```

## Best Practices

### 1. Resource Management

```javascript
// Always dispose of the client
useEffect(() => {
  const client = new MiltonAsyncClient(config);
  
  return () => {
    client.dispose(); // Clean up resources
  };
}, []);
```

### 2. Error Handling

```javascript
// Comprehensive error handling
const handleRequest = async () => {
  try {
    await client.submitUserMessage(data, {
      onError: (error) => {
        // Handle processing errors
        logError('Processing error:', error);
      }
    });
  } catch (error) {
    // Handle submission errors
    logError('Submission error:', error);
  }
};
```

### 3. Status Management

```javascript
// Track request states
const [requests, setRequests] = useState(new Map());

const trackRequest = (id, type) => {
  setRequests(prev => new Map(prev.set(id, { type, status: 'submitted' })));
};

const updateRequest = (id, updates) => {
  setRequests(prev => {
    const newMap = new Map(prev);
    const existing = newMap.get(id);
    if (existing) {
      newMap.set(id, { ...existing, ...updates });
    }
    return newMap;
  });
};
```

### 4. Performance Optimization

```javascript
// Use appropriate polling intervals
const client = new MiltonAsyncClient({
  pollingConfig: {
    intervals: [5, 10, 20, 40, 80, 120], // Exponential backoff up to 120 seconds
    batteryOptimized: true,
    maxAttempts: 6
  }
});

// Enable push notifications for better performance
const client = new MiltonAsyncClient({
  enablePushNotifications: true // Reduces polling overhead
});
```

For more examples and detailed usage patterns, see the [examples directory](examples/) and [migration guide](MIGRATION_GUIDE.md).