# TypeScript Definitions

This document provides TypeScript definitions for the Milton Health Coach FCM Client SDK. While the SDK is implemented in JavaScript, these definitions enable full TypeScript support in your React Native projects.

## Installation with TypeScript

```bash
npm install milton-fcm-client-sdk
npm install --save-dev @types/react-native
```

## Type Definitions

### Core Types

```typescript
// Configuration Types
export interface MiltonSDKConfig {
  baseUrl: string;
  apiKey: string;
  timeout?: number;
  enablePushNotifications?: boolean;
  clientIdConfig?: ClientIdConfig;
  pollingConfig?: PollingConfig;
  offlineConfig?: OfflineConfig;
}

export interface ClientIdConfig {
  autoGenerate?: boolean;
  prefix?: string;
  includeDeviceInfo?: boolean;
  includePlatform?: boolean;
  includeAppVersion?: boolean;
  customClientId?: string;
  storageKey?: string;
}

export interface PollingConfig {
  intervals?: number[];
  maxAttempts?: number;
  timeoutMs?: number;
  backgroundIntervals?: number[];
  batteryOptimized?: boolean;
}

export interface OfflineConfig {
  enableOfflineQueue?: boolean;
  maxQueueSize?: number;
  retryAttempts?: number;
  retryDelay?: number;
  storageKey?: string;
}

// Request Types
export interface UserMessageRequest {
  orgId: number;
  userId: number;
  question: string;
  image?: string;
  sessionId?: string;
}

export interface SurveyRequest {
  phone_number: string;
  survey: string;
  birthday: string;
  default_timezone: string;
}



// Response Types
export interface AsyncRequestResponse {
  request_id: string;
  status: 'accepted' | 'queued_offline';
  polling_url?: string;
  estimated_completion_time?: string;
  webhook_url?: string;
}

export interface RequestStatus {
  request_id: string;
  status: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'waiting_for_push';
  result?: any;
  error?: string;
  created_at: string;
  updated_at: string;
  expires_at: string;
  message?: string;
}

// Callback Types
export interface RequestOptions {
  webhookUrl?: string;
  clientId?: string;
  onProgress?: (status: RequestStatus) => void;
  onComplete?: (result: any) => void;
  onError?: (error: Error) => void;
}

// SDK Information Types
export interface SDKInfo {
  name: string;
  version: string;
  clientId: string | null;
  configuration: SDKConfiguration;
  status: SDKStatus;
}

export interface SDKConfiguration {
  baseUrl: string;
  enablePushNotifications: boolean;
  pollingIntervals: number[];
  maxPollingAttempts: number;
  batteryOptimized: boolean;
  offlineQueueEnabled: boolean;
  maxOfflineQueueSize: number;
}

export interface SDKStatus {
  fcmToken: string;
  isOnline: boolean;
  isInBackground: boolean;
  activePollingRequests: number;
  offlineQueueLength: number;
}

// Offline Queue Types
export interface OfflineQueueStatus {
  queueLength: number;
  isOnline: boolean;
  isInBackground: boolean;
  activePollingRequests: number;
}

export interface QueueItem {
  id: string;
  endpoint: string;
  requestData: any;
  options: RequestOptions;
  timestamp: number;
  retryCount: number;
}
```

### Main SDK Class

```typescript
export declare class MiltonAsyncClient {
  constructor(config: MiltonSDKConfig);

  // Core Methods
  submitUserMessage(
    request: UserMessageRequest,
    options?: RequestOptions
  ): Promise<AsyncRequestResponse>;

  submitSurvey(
    request: SurveyRequest,
    options?: RequestOptions
  ): Promise<AsyncRequestResponse>;



  // Status Management
  getRequestStatus(requestId: string): Promise<RequestStatus>;
  cancelRequest(requestId: string): Promise<void>;

  // Client ID Management
  getClientId(): string | null;
  setClientId(clientId: string): Promise<void>;
  regenerateClientId(): Promise<void>;

  // SDK Information
  getSDKInfo(): SDKInfo;

  // Offline Management
  getOfflineQueueStatus(): OfflineQueueStatus;
  clearOfflineQueue(): Promise<void>;

  // Lifecycle
  dispose(): void;
}
```

## Usage Examples with TypeScript

### Basic Setup

```typescript
import { MiltonAsyncClient, MiltonSDKConfig, UserMessageRequest, RequestOptions } from 'milton-fcm-client-sdk';

const config: MiltonSDKConfig = {
  baseUrl: 'https://api.milton.com',
  apiKey: 'your-api-key',
  enablePushNotifications: true,
  clientIdConfig: {
    autoGenerate: true,
    prefix: 'myapp',
    includeDeviceInfo: true,
    includePlatform: true,
    includeAppVersion: true
  },
  pollingConfig: {
    intervals: [1, 2, 4, 8, 15, 30],
    maxAttempts: 6,
    batteryOptimized: true
  }
};

const client = new MiltonAsyncClient(config);
```

### Client ID Management with TypeScript

```typescript
// Get current client ID
const clientId: string | null = client.getClientId();
console.log('Current client ID:', clientId);

// Set custom client ID
await client.setClientId('my-custom-client-id');

// Regenerate client ID
await client.regenerateClientId();

// Get SDK information
const sdkInfo: SDKInfo = client.getSDKInfo();
console.log('SDK Version:', sdkInfo.version);
console.log('Configuration:', sdkInfo.configuration);
console.log('Status:', sdkInfo.status);

// Use client ID in request options
const options: RequestOptions = {
  clientId: 'request-specific-id',
  onComplete: (result: any) => {
    console.log('Request completed:', result);
  }
};
```

### User Message with TypeScript

```typescript
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, Alert } from 'react-native';
import { MiltonAsyncClient, UserMessageRequest, RequestOptions, RequestStatus } from 'milton-fcm-client-sdk';

interface Props {
  client: MiltonAsyncClient;
  orgId: number;
  userId: number;
}

const UserMessageComponent: React.FC<Props> = ({ client, orgId, userId }) => {
  const [question, setQuestion] = useState<string>('');
  const [status, setStatus] = useState<string>('');
  const [loading, setLoading] = useState<boolean>(false);

  const handleSubmit = async (): Promise<void> => {
    if (!question.trim()) {
      Alert.alert('Error', 'Please enter a question');
      return;
    }

    setLoading(true);

    const request: UserMessageRequest = {
      orgId,
      userId,
      question: question.trim(),
    };

    const options: RequestOptions = {
      onProgress: (status: RequestStatus) => {
        setStatus(`Processing: ${status.status}`);
      },
      onComplete: (result: any) => {
        setStatus('Completed!');
        setLoading(false);
        console.log('Result:', result);
      },
      onError: (error: Error) => {
        setStatus(`Error: ${error.message}`);
        setLoading(false);
        Alert.alert('Error', error.message);
      }
    };

    try {
      const response = await client.submitUserMessage(request, options);
      setStatus(`Submitted: ${response.request_id}`);
    } catch (error) {
      setLoading(false);
      Alert.alert('Error', `Failed to submit: ${error}`);
    }
  };

  return (
    <View>
      <TextInput
        value={question}
        onChangeText={setQuestion}
        placeholder="Ask Milton a question..."
        multiline
      />
      <TouchableOpacity onPress={handleSubmit} disabled={loading}>
        <Text>{loading ? 'Processing...' : 'Submit'}</Text>
      </TouchableOpacity>
      {status ? <Text>Status: {status}</Text> : null}
    </View>
  );
};

export default UserMessageComponent;
```

### Survey Submission with TypeScript

```typescript
import React, { useState } from 'react';
import { MiltonAsyncClient, SurveyRequest, RequestOptions } from 'milton-fcm-client-sdk';

interface SurveyData {
  mood: 'excellent' | 'good' | 'fair' | 'poor';
  energy_level: number; // 1-10
  sleep_hours: number;
  stress_level: number; // 1-10
  exercise_minutes?: number;
}

interface Props {
  client: MiltonAsyncClient;
  orgId: number;
  userId: number;
}

const SurveyComponent: React.FC<Props> = ({ client, orgId, userId }) => {
  const [surveyData, setSurveyData] = useState<SurveyData>({
    mood: 'good',
    energy_level: 7,
    sleep_hours: 8,
    stress_level: 3,
  });

  const submitSurvey = async (): Promise<void> => {
    const request: SurveyRequest = {
      orgId,
      userId,
      surveyData,
    };

    const options: RequestOptions = {
      onComplete: (result: any) => {
        console.log('Survey processed:', result);
      },
      onError: (error: Error) => {
        console.error('Survey failed:', error);
      }
    };

    try {
      await client.submitSurvey(request, options);
    } catch (error) {
      console.error('Failed to submit survey:', error);
    }
  };

  return (
    // Survey UI components here
    <></>
  );
};
```



### Advanced Configuration with TypeScript

```typescript
import { MiltonAsyncClient, MiltonSDKConfig, PollingConfig, OfflineConfig } from 'milton-fcm-client-sdk';

// Custom polling configuration
const pollingConfig: PollingConfig = {
  intervals: [1, 3, 6, 12, 30], // Custom intervals in seconds
  maxAttempts: 5,
  timeoutMs: 45000,
  backgroundIntervals: [30, 60, 120, 300],
  batteryOptimized: true
};

// Custom offline configuration
const offlineConfig: OfflineConfig = {
  enableOfflineQueue: true,
  maxQueueSize: 100,
  retryAttempts: 5,
  retryDelay: 3000,
  storageKey: 'milton_custom_queue'
};

// Complete SDK configuration
const config: MiltonSDKConfig = {
  baseUrl: process.env.MILTON_API_URL || 'https://api.milton.com',
  apiKey: process.env.MILTON_API_KEY || '',
  timeout: 60000,
  enablePushNotifications: true,
  pollingConfig,
  offlineConfig
};

const client = new MiltonAsyncClient(config);
```

### Error Handling with TypeScript

```typescript
import { MiltonAsyncClient, RequestOptions } from 'milton-fcm-client-sdk';

class MiltonError extends Error {
  constructor(
    message: string,
    public code?: string,
    public statusCode?: number
  ) {
    super(message);
    this.name = 'MiltonError';
  }
}

const handleMiltonRequest = async (client: MiltonAsyncClient): Promise<void> => {
  const options: RequestOptions = {
    onError: (error: Error) => {
      if (error.message.includes('HTTP 503')) {
        // Server overloaded
        throw new MiltonError('Server is temporarily overloaded', 'SERVER_OVERLOAD', 503);
      } else if (error.message.includes('HTTP 401')) {
        // Unauthorized
        throw new MiltonError('Invalid API key', 'UNAUTHORIZED', 401);
      } else if (error.message.includes('offline')) {
        // Offline error
        throw new MiltonError('Device is offline', 'OFFLINE');
      } else {
        // Generic error
        throw new MiltonError(error.message, 'UNKNOWN');
      }
    }
  };

  try {
    await client.submitUserMessage({
      orgId: 123,
      userId: 456,
      question: 'Test question'
    }, options);
  } catch (error) {
    if (error instanceof MiltonError) {
      console.error(`Milton Error [${error.code}]:`, error.message);
      // Handle specific error types
      switch (error.code) {
        case 'SERVER_OVERLOAD':
          // Retry after delay
          break;
        case 'UNAUTHORIZED':
          // Refresh API key
          break;
        case 'OFFLINE':
          // Show offline message
          break;
      }
    } else {
      console.error('Unexpected error:', error);
    }
  }
};
```

### React Hook with TypeScript

```typescript
import { useState, useEffect, useCallback } from 'react';
import { MiltonAsyncClient, RequestStatus, AsyncRequestResponse } from 'milton-fcm-client-sdk';

interface UseMiltonRequestResult {
  submitRequest: (question: string) => Promise<void>;
  status: RequestStatus | null;
  result: any;
  error: Error | null;
  loading: boolean;
}

export const useMiltonRequest = (
  client: MiltonAsyncClient,
  orgId: number,
  userId: number
): UseMiltonRequestResult => {
  const [status, setStatus] = useState<RequestStatus | null>(null);
  const [result, setResult] = useState<any>(null);
  const [error, setError] = useState<Error | null>(null);
  const [loading, setLoading] = useState<boolean>(false);

  const submitRequest = useCallback(async (question: string): Promise<void> => {
    setLoading(true);
    setError(null);
    setResult(null);
    setStatus(null);

    try {
      await client.submitUserMessage({
        orgId,
        userId,
        question,
      }, {
        onProgress: (status: RequestStatus) => {
          setStatus(status);
        },
        onComplete: (result: any) => {
          setResult(result);
          setLoading(false);
        },
        onError: (error: Error) => {
          setError(error);
          setLoading(false);
        }
      });
    } catch (err) {
      setError(err as Error);
      setLoading(false);
    }
  }, [client, orgId, userId]);

  return {
    submitRequest,
    status,
    result,
    error,
    loading
  };
};

// Usage in component
const MyComponent: React.FC = () => {
  const client = new MiltonAsyncClient({ /* config */ });
  const { submitRequest, status, result, error, loading } = useMiltonRequest(client, 123, 456);

  const handleSubmit = () => {
    submitRequest('What should I eat for breakfast?');
  };

  return (
    // Component JSX
    <></>
  );
};
```

## Type Declaration File

Create `types/milton-fcm-client-sdk.d.ts` in your project:

```typescript
declare module 'milton-fcm-client-sdk' {
  export interface MiltonSDKConfig {
    baseUrl: string;
    apiKey: string;
    timeout?: number;
    enablePushNotifications?: boolean;
    pollingConfig?: PollingConfig;
    offlineConfig?: OfflineConfig;
  }

  export interface PollingConfig {
    intervals?: number[];
    maxAttempts?: number;
    timeoutMs?: number;
    backgroundIntervals?: number[];
    batteryOptimized?: boolean;
  }

  export interface OfflineConfig {
    enableOfflineQueue?: boolean;
    maxQueueSize?: number;
    retryAttempts?: number;
    retryDelay?: number;
    storageKey?: string;
  }

  export interface UserMessageRequest {
    orgId: number;
    userId: number;
    question: string;
    image?: string;
    sessionId?: string;
  }

  export interface SurveyRequest {
    phone_number: string;
    survey: string;
    birthday: string;
    default_timezone: string;
  }



  export interface AsyncRequestResponse {
    request_id: string;
    status: 'accepted' | 'queued_offline';
    polling_url?: string;
    estimated_completion_time?: string;
    webhook_url?: string;
  }

  export interface RequestStatus {
    request_id: string;
    status: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'waiting_for_push';
    result?: any;
    error?: string;
    created_at: string;
    updated_at: string;
    expires_at: string;
    message?: string;
  }

  export interface RequestOptions {
    webhookUrl?: string;
    clientId?: string;
    onProgress?: (status: RequestStatus) => void;
    onComplete?: (result: any) => void;
    onError?: (error: Error) => void;
  }

  export interface OfflineQueueStatus {
    queueLength: number;
    isOnline: boolean;
    isInBackground: boolean;
    activePollingRequests: number;
  }

  export class MiltonAsyncClient {
    constructor(config: MiltonSDKConfig);

    submitUserMessage(
      request: UserMessageRequest,
      options?: RequestOptions
    ): Promise<AsyncRequestResponse>;

    submitSurvey(
      request: SurveyRequest,
      options?: RequestOptions
    ): Promise<AsyncRequestResponse>;



    getRequestStatus(requestId: string): Promise<RequestStatus>;
    cancelRequest(requestId: string): Promise<void>;
    getOfflineQueueStatus(): OfflineQueueStatus;
    clearOfflineQueue(): Promise<void>;
    dispose(): void;
  }
}
```

## TypeScript Configuration

Update your `tsconfig.json`:

```json
{
  "compilerOptions": {
    "target": "es2017",
    "lib": ["es2017", "es6", "dom"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src/**/*",
    "types/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}
```

This provides complete TypeScript support for the Milton Health Coach FCM Client SDK, enabling type safety, IntelliSense, and better development experience in TypeScript React Native projects.