> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pnta.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugin Methods

> Complete API documentation for PNTA Flutter plugin

## Core Methods

### `initialize()`

```dart theme={null}
PntaFlutter.initialize(String projectId, {
  Map<String, dynamic>? metadata,
  bool registerDevice = true,
  bool autoHandleLinks = false,
  bool showSystemUI = false,
})
```

Initializes the plugin and optionally registers the device. When `registerDevice: true` (default), this method will prompt the user for notification permission and register the device with PNTA. Use `registerDevice: false` for delayed registration if you don't want to prompt the user immediately.

**Parameters:**

* `projectId`: Your PNTA project ID (format: `prj_XXXXXXXXX`)
* `metadata` (optional): Device metadata as key-value pairs
* `registerDevice` (optional): Whether to register device immediately. Default: `true`
* `autoHandleLinks` (optional): Automatically handle `link_to` URLs when notifications are tapped from background/terminated state. Default: `false`
* `showSystemUI` (optional): Show system notification banner/sound when app is in foreground. Default: `false`

**Returns:** `Future<void>`

**Examples:**

```dart lib/main.dart theme={null}
// Minimal - handles everything automatically
await PntaFlutter.initialize('prj_XXXXXXXXX');

// With metadata and configuration
await PntaFlutter.initialize(
  'prj_XXXXXXXXX',
  metadata: {
    'user_id': '123',
    'user_email': 'user@example.com',
  },
  autoHandleLinks: true,  // Optional: enable auto-handling of links
  showSystemUI: true,     // Optional: show system UI in foreground
);

// Delayed registration scenario
await PntaFlutter.initialize(
  'prj_XXXXXXXXX',
  metadata: {
    'user_id': '123',
    'user_email': 'user@example.com',
  },
  registerDevice: false,  // Don't register immediately
  autoHandleLinks: true,
);
// Register later with registerDevice()
```

### `registerDevice()`

```dart theme={null}
PntaFlutter.registerDevice()
```

Registers the device with your PNTA project using metadata from `initialize()`. Only needed when using delayed registration (when `initialize()` was called with `registerDevice: false`).

**Returns:** `Future<void>`

**Example:**

```dart lib/main.dart theme={null}
// First initialize with metadata but don't register
await PntaFlutter.initialize(
  'prj_XXXXXXXXX',
  metadata: {
    'user_id': '123',
    'user_email': 'user@example.com',
  },
  registerDevice: false,
);

// Later, register when ready (uses stored metadata)
await PntaFlutter.registerDevice();

// Get device token after registration
final token = PntaFlutter.deviceToken;
if (token != null) {
  print('Device registered with token: $token');
}
```

<Note>
  Must call `initialize()` first. Only use this method when you initialized with `registerDevice: false`.
</Note>

### `updateMetadata()`

```dart theme={null}
PntaFlutter.updateMetadata(Map<String, dynamic> metadata)
```

Updates device metadata without re-registering.

**Parameters:**

* `metadata`: Updated metadata as key-value pairs

**Returns:** `Future<void>`

**Example:**

```dart lib/main.dart theme={null}
await PntaFlutter.updateMetadata({
  'last_active': DateTime.now().toIso8601String(),
});
```

### `handleLink()`

```dart theme={null}
PntaFlutter.handleLink(String link)
```

Manually handles a link using the plugin's routing logic.

**Parameters:**

* `link`: The link to handle

**Returns:** `void`

**Example:**

```dart lib/main.dart theme={null}
PntaFlutter.handleLink('/profile');
PntaFlutter.handleLink('https://example.com');
```

## Properties

### `deviceToken`

```dart theme={null}
PntaFlutter.deviceToken
```

Gets the current device token after successful initialization or registration.

**Type:** `String?`

**Returns:** Device token string if registration was successful, `null` otherwise.

**Example:**

```dart lib/main.dart theme={null}
await PntaFlutter.initialize('prj_XXXXXXXXX');

final token = PntaFlutter.deviceToken;
if (token != null) {
  print('Device token: $token');
} else {
  print('Device registration failed or not completed');
}
```

### `navigatorKey`

```dart theme={null}
PntaFlutter.navigatorKey
```

Global navigator key for internal route navigation. Must be assigned to your `MaterialApp`.

**Type:** `GlobalKey<NavigatorState>`

**Example:**

```dart lib/main.dart theme={null}
MaterialApp(
  navigatorKey: PntaFlutter.navigatorKey,
  // ... rest of your app
)
```

### `foregroundNotifications`

```dart theme={null}
PntaFlutter.foregroundNotifications
```

Stream of notification payloads received when app is in foreground.

**Type:** `Stream<Map<String, dynamic>>`

**Payload Structure:**

Both iOS and Android send identical flat payload structures:

```json theme={null}
{
  "title": "Rain expected this afternoon",
  "body": "Showers from 2–5 PM in your area...",
  "link_to": "https://example.com/weather",
  "custom_field": "custom_value"
}
```

**Example:**

```dart lib/main.dart theme={null}
PntaFlutter.foregroundNotifications.listen((payload) {
  final title = payload['title'];
  final body = payload['body'];
  final link = payload['link_to'];
  
  print('Received: $title');

  // Show custom UI
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text('$title: $body')),
  );
});
```

### `onNotificationTap`

```dart theme={null}
PntaFlutter.onNotificationTap
```

Stream of notification payloads when user taps a notification from background/terminated state.

**Type:** `Stream<Map<String, dynamic>>`

**Payload Structure:**

Contains the `link_to` field and any custom data fields. System fields (`title`, `body`) are not available on Android due to platform limitations.

```json theme={null}
{
  "link_to": "https://example.com/weather"
}
```

**Example:**

```dart lib/main.dart theme={null}
PntaFlutter.onNotificationTap.listen((payload) {
  print('User tapped notification: $payload');
  
  // Access link_to field (available on both platforms)
  final linkTo = payload['link_to'] as String?;
  
  // Track analytics, navigate to specific screen, etc.
});
```

## Link Handling

The plugin handles notification links automatically using smart URL detection:

* **External URLs** (with scheme) → Opens in system browser/apps
  * Examples: `https://example.com`, `mailto:test@example.com`, `tel:+1234567890`, `sms:+1234567890`
  * Works automatically with no additional configuration required
* **Internal routes** (without scheme) → Navigates using Flutter's Navigator
  * Examples: `/profile`, `/settings`, `/dashboard`
  * Requires `navigatorKey` setup (covered in Quick Start)

## Implementing Notification Listeners

### App-Level

Global listeners in `main.dart`. No disposal needed since the app doesn't get disposed.

```dart theme={null}
void main() async {
  await PntaFlutter.initialize('prj_XXXXXXXXX');

  PntaFlutter.foregroundNotifications.listen((payload) {
    print('Got notification: ${payload['title']}');
  });

  runApp(MyApp());
}
```

### Widget-Level

Listeners in StatefulWidgets. Disposal required to prevent memory leaks.

```dart theme={null}
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  StreamSubscription? _sub;

  @override
  void initState() {
    super.initState();
    _sub = PntaFlutter.foregroundNotifications.listen((payload) {
      // Handle notification
    });
  }

  @override
  void dispose() {
    _sub?.cancel(); // Required to prevent memory leaks
    super.dispose();
  }
}
```
