# Push Notification System - Setup & Configuration Guide

## Overview

Complete push notification system for Disrupt Radio platform supporting Web, Android, and iOS.

## Database Setup

Run the migrations to create necessary tables:

```bash
php artisan migrate
```

This will create:

- `push_subscriptions` - Stores device tokens and subscription info
- `notification_preferences` - Stores user content subscription preferences
- `notification_logs` - Tracks all sent notifications

## Backend Configuration

### 1. Install Web Push Library

```bash
composer require minishlink/web-push
```

### 2. Generate VAPID Keys

Generate VAPID keys for web push notifications:

```bash
php artisan webpush:vapid
```

Or generate manually using online tools or this PHP code:

```php
<?php
require 'vendor/autoload.php';
use Minishlink\WebPush\VAPID;

$keys = VAPID::createVapidKeys();
echo "Public Key: " . $keys['publicKey'] . "\n";
echo "Private Key: " . $keys['privateKey'] . "\n";
```

### 3. Environment Variables

Add these to your `.env` file:

```env
# Web Push Notifications (VAPID)
VAPID_PUBLIC_KEY=your_public_key_here
VAPID_PRIVATE_KEY=your_private_key_here

# Firebase Cloud Messaging (for mobile apps)
FCM_SERVER_KEY=your_fcm_server_key_here
```

### 4. Queue Configuration

For better performance, configure queues to handle notifications asynchronously:

```env
QUEUE_CONNECTION=database
```

Then run:

```bash
php artisan queue:table
php artisan migrate
php artisan queue:work
```

## Frontend Setup

### 1. Service Worker

The service worker is already created at `/public/service-worker.js` and will be automatically registered.

### 2. Include Scripts & Styles

Scripts and styles are already included in the main layout file:

```blade
<!-- In resources/views/layouts/front/main.blade.php -->
<link href="{{ asset('css/push-notifications.css') }}" rel="stylesheet">
<script src="{{ asset('js/push-notifications.js') }}"></script>
<script src="{{ asset('js/notification-bell.js') }}"></script>
```

### 3. Add Notification Bells

Add notification bells to any content using the `data-notification-bell` attribute:

```blade
<div data-notification-bell
     data-content-type="program"
     data-content-id="123"
     data-content-name="Program Name">
</div>
```

Content types supported:

- `program` - Radio programs
- `podcast` - Podcast series
- `episode` - Individual episodes
- `live_show` - Live broadcasts

## Usage Examples

### Trigger Notification When Content is Published

#### In Controllers:

```php
// When creating a new episode
public function store(Request $request)
{
    $episode = Audio::create($request->all());

    // Trigger notification
    notifyNewEpisode($episode);

    return response()->json(['success' => true]);
}

// When creating a new program
public function store(Request $request)
{
    $program = Program::create($request->all());

    notifyNewProgram($program);

    return response()->json(['success' => true]);
}

// When creating a new podcast
public function store(Request $request)
{
    $podcast = Album::create($request->all());

    notifyNewPodcast($podcast);

    return response()->json(['success' => true]);
}

// When a live show starts
public function goLive($programId)
{
    $program = Program::find($programId);

    notifyLiveShow($program);

    return response()->json(['success' => true]);
}
```

#### Using Event Directly:

```php
use App\Events\NewContentPublished;

event(new NewContentPublished('episode', $episodeId, $episodeName, $programId, $programName));
```

### Check Subscription Status

```javascript
const result = await window.pushNotificationManager.checkSubscription(
  "program",
  123
);
console.log(result.is_subscribed); // true or false
```

### Subscribe/Unsubscribe

```javascript
// Toggle subscription
const result = await window.pushNotificationManager.toggleContentSubscription(
  "program",
  123
);
```

## Mobile App Integration (FCM)

### Android Setup

1. Add Firebase to your Android project
2. Get the FCM server key from Firebase Console
3. Add to `.env`:

```env
FCM_SERVER_KEY=your_fcm_server_key
```

4. In your Android app, send device token to backend:

```kotlin
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val token = task.result
        // Send to backend
        apiService.subscribeToNotifications(token, "android")
    }
}
```

5. Handle notifications:

```kotlin
class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        val data = remoteMessage.data
        val type = data["type"]
        val id = data["id"]
        val url = data["url"]

        // Handle deep linking based on type and id
        when (type) {
            "program" -> openProgram(id)
            "podcast" -> openPodcast(id)
            "episode" -> openEpisode(id)
            "live_show" -> openLiveShow(id)
        }
    }
}
```

### iOS Setup

1. Enable Push Notifications in Xcode
2. Get APNs certificate and upload to Firebase
3. Use FCM for iOS:

```swift
Messaging.messaging().token { token, error in
    if let token = token {
        // Send to backend
        apiService.subscribeToNotifications(token: token, deviceType: "ios")
    }
}
```

## API Endpoints

All endpoints are prefixed with `/notifications/`:

- `GET /notifications/vapid-public-key` - Get VAPID public key
- `POST /notifications/subscribe` - Subscribe device to push notifications
- `POST /notifications/unsubscribe` - Unsubscribe device
- `POST /notifications/subscribe-content` - Subscribe to specific content
- `POST /notifications/unsubscribe-content` - Unsubscribe from content
- `POST /notifications/toggle-subscription` - Toggle content subscription
- `GET /notifications/preferences` - Get user's notification preferences
- `POST /notifications/update-settings` - Update notification settings
- `GET /notifications/check-subscription` - Check subscription status

## User Settings Page

Users can manage their notification preferences at:

```
/notification-settings
```

This page allows users to:

- Enable/disable push notifications
- View all subscribed programs/podcasts
- Toggle notifications for each item individually

## Testing

### Test Web Push:

1. Open browser console on your site
2. Run:

```javascript
window.pushNotificationManager.requestPermission().then((result) => {
  console.log("Permission result:", result);
});
```

3. Subscribe to content:

```javascript
window.pushNotificationManager
  .toggleContentSubscription("program", 1)
  .then((result) => {
    console.log("Subscription result:", result);
  });
```

4. Trigger a test notification from backend:

```php
use App\Services\PushNotificationService;

$service = new PushNotificationService();
$service->notifySubscribers('program', 1, 'Test Notification', 'This is a test', url('/'));
```

## Troubleshooting

### "Web Push not configured" Error

- Ensure VAPID keys are set in `.env`
- Run `php artisan config:cache`

### Notifications Not Received

- Check browser console for errors
- Verify service worker is registered: Chrome DevTools > Application > Service Workers
- Check notification permission: Chrome Settings > Site Settings > Notifications
- Ensure HTTPS (required for web push, except localhost)

### Subscription Not Saved

- Verify CSRF token is present on the page
- Check network tab for failed API requests
- Ensure user is authenticated for content-specific subscriptions

### Mobile Notifications Not Working

- Verify FCM_SERVER_KEY is correct
- Check device token is being sent to backend
- Ensure app has notification permissions
- Test with Firebase Console direct send first

## Performance Optimization

### Use Queues

Notifications are sent via queued jobs for better performance:

```bash
php artisan queue:work --tries=3
```

### Cleanup Old Logs

Create a scheduled task to clean old notification logs:

```php
// In app/Console/Kernel.php
protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        \App\NotificationLog::where('created_at', '<', now()->subDays(30))->delete();
    })->daily();
}
```

## Security Considerations

1. **HTTPS Required**: Web Push only works over HTTPS (except localhost)
2. **VAPID Keys**: Keep private key secret, never expose in frontend code
3. **FCM Server Key**: Store securely, never commit to repository
4. **Rate Limiting**: Implement rate limiting on notification endpoints
5. **User Privacy**: Always require user consent before subscribing
6. **Unsubscribe**: Always provide easy way to unsubscribe

## Browser Support

- Chrome/Edge: ✅ Full support
- Firefox: ✅ Full support
- Safari: ✅ iOS 16.4+, macOS 13+
- Opera: ✅ Full support
- Internet Explorer: ❌ Not supported

## License

This notification system is part of the Disrupt Radio platform.
