# Mobile App Integration Guide

## `@haykmkrtich/react-native-patriot-native`

A guide for integrating WearOS watch communication into your React Native mobile app.

---

## Prerequisites

| Requirement | Minimum |
|---|---|
| React Native | >= 0.77.0 (New Architecture / TurboModules) |
| Android API | 24+ (Android 7.0) |
| Java | 17+ |
| Hardware | Paired WearOS watch |
| Platform | Android only (iOS calls are rejected) |

---

## 1. Install the Package

```bash
npm install @haykmkrtich/react-native-patriot-native
# or
yarn add @haykmkrtich/react-native-patriot-native
```

No manual linking needed — TurboModule autolinking handles it. After installing, rebuild:

```bash
npx react-native clean
npx react-native run-android
```

---

## 2. Exported API

```typescript
import {
  getConnectedDevices,
  installWatchface,
  isAppInstalledOnWatch,
  sendMessageToWatch,
} from '@haykmkrtich/react-native-patriot-native';
```

| Function | Purpose |
|---|---|
| `getConnectedDevices()` | List all connected WearOS watches |
| `installWatchface(packageName, nodeId?)` | Trigger Play Store install on a specific or all watches |
| `isAppInstalledOnWatch(packageName)` | Check if an app/capability exists on watches |
| `sendMessageToWatch(nodeId, path, data?)` | Send a message to one specific watch |

---

## 3. TypeScript Types

```typescript
interface ConnectedDevice {
  id: string;           // Node ID — use this for sendMessageToWatch
  displayName: string;  // e.g. "Galaxy Watch 5"
  isNearby: boolean;    // Bluetooth proximity
  type: string;         // "watch"
  platform: string;     // "wearOS" | "unknown"
}

interface AppInstallStatus {
  isInstalled: boolean;       // true if found on any watch
  installedOnNodes: string[]; // node IDs where it's installed
}
```

---

## 4. Common Workflows

### A. Discover Connected Watches

```typescript
const devices = await getConnectedDevices();
// Returns ConnectedDevice[] — empty array if nothing connected
```

### B. Install a Watchface on All Connected Watches

Omit the second argument to broadcast to every connected watch.

```typescript
await installWatchface('com.example.mywatchface');
// Opens Play Store install prompt on ALL connected watches
```

### C. Install a Watchface on a Specific Watch

Pass the `nodeId` from `getConnectedDevices()` to target one watch.

```typescript
const devices = await getConnectedDevices();

if (devices.length === 0) {
  throw new Error('No watch connected');
}

// Target the first (or only) connected watch
const watch = devices[0];
await installWatchface('com.example.mywatchface', watch.id);
// Opens Play Store install prompt only on that watch
```

### D. Full Flow: Check Then Install on a Specific Watch

```typescript
async function installOnWatch(packageName: string): Promise<void> {
  // Step 1: Get connected watches
  const devices = await getConnectedDevices();

  if (devices.length === 0) {
    throw new Error('No watch connected');
  }

  const watch = devices[0];
  console.log(`Found: ${watch.displayName}`);

  // Step 2: (Optional) Check if already installed
  const status = await isAppInstalledOnWatch(packageName);
  if (status.isInstalled) {
    console.log('Already installed, skipping');
    return;
  }

  // Step 3: Install on that specific watch
  await installWatchface(packageName, watch.id);
  // Phone shows a toast, watch shows Play Store install prompt
}

await installOnWatch('com.example.mywatchface');
```

### E. Send a Custom Message to a Specific Watch

Use `sendMessageToWatch` to send arbitrary data to a watch node.

```typescript
const devices = await getConnectedDevices();
const watch = devices[0];

// path = routing key, data = optional string payload
await sendMessageToWatch(watch.id, '/sync-settings', JSON.stringify({
  theme: 'dark',
}));
```

---

## 5. Error Handling

Every function rejects with an `Error` that has a `.code` property:

```typescript
try {
  await installWatchface('com.example.watchface');
} catch (error: any) {
  switch (error.code) {
    case 'NO_NODES':
      // No watches connected
      break;
    case 'INSTALL_FAILED':
      // WearOS API rejected the install request
      break;
  }
}
```

| Error Code | Thrown By | Meaning |
|---|---|---|
| `NO_NODES` | `installWatchface` | No connected WearOS device |
| `INSTALL_FAILED` | `installWatchface` | Install request failed |
| `DETECTION_FAILED` | `getConnectedDevices` | WearOS API communication error |
| `CHECK_FAILED` | `isAppInstalledOnWatch` | Capability query failed |
| `MESSAGE_FAILED` | `sendMessageToWatch` | Message delivery failed |

Any call on iOS rejects with `"PatriotNative is only supported on Android"`.

---

## 6. Full Example: Install Screen Component

```typescript
import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert, Platform } from 'react-native';
import {
  getConnectedDevices,
  installWatchface,
  isAppInstalledOnWatch,
  ConnectedDevice,
} from '@haykmkrtich/react-native-patriot-native';

const WATCHFACE_PACKAGE = 'com.example.mywatchface';

export function WatchInstallScreen() {
  const [watch, setWatch] = useState<ConnectedDevice | null>(null);
  const [installed, setInstalled] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (Platform.OS !== 'android') return;

    (async () => {
      try {
        const devices = await getConnectedDevices();
        if (devices.length > 0) {
          setWatch(devices[0]);

          const status = await isAppInstalledOnWatch(WATCHFACE_PACKAGE);
          setInstalled(status.isInstalled);
        }
      } catch (e) {
        console.error(e);
      } finally {
        setLoading(false);
      }
    })();
  }, []);

  const handleInstall = async () => {
    try {
      // Target the specific connected watch by its node ID
      await installWatchface(WATCHFACE_PACKAGE, watch!.id);
      Alert.alert('Success', 'Install prompt sent to your watch');
    } catch (error: any) {
      if (error.code === 'NO_NODES') {
        Alert.alert('Error', 'No watch connected');
      } else {
        Alert.alert('Error', 'Installation failed');
      }
    }
  };

  if (Platform.OS !== 'android') {
    return <Text>WearOS features are only available on Android</Text>;
  }

  if (loading) return <Text>Detecting watch...</Text>;

  if (!watch) return <Text>No watch connected</Text>;

  return (
    <View>
      <Text>Connected: {watch.displayName}</Text>
      <Text>Nearby: {watch.isNearby ? 'Yes' : 'No'}</Text>
      <Text>Platform: {watch.platform}</Text>

      {installed ? (
        <Text>Watchface already installed</Text>
      ) : (
        <Button title="Install Watchface" onPress={handleInstall} />
      )}
    </View>
  );
}
```

---

## 7. Important Notes

1. **Android only** — always gate calls behind `Platform.OS === 'android'` or let the library's built-in check reject gracefully.

2. **`installWatchface` supports targeting** — pass a `nodeId` (from `getConnectedDevices()`) to install on a specific watch, or omit it to broadcast to all connected watches.

3. **Google Play pairing** — for production, the mobile app and WearOS app must share the same package name in Google Play Console. This is a Google requirement, not a library limitation.

4. **Deprecated API** — do NOT use `getConnectedWatchProperties()`. Use `getConnectedDevices()` instead.

5. **All functions are async** — every call returns a `Promise`. Always `await` or handle `.then()/.catch()`.

6. **Rebuild after install** — this is a native module. `npx react-native clean && npx react-native run-android` is required after adding the package. Hot reload alone won't pick it up.
