# Notification System Documentation

## Overview

This platform uses a unified, professional notification system built on Laravel's event-listener architecture with FCM (Firebase Cloud Messaging) support for push notifications.

## Architecture

### Core Components

1. **AppNotification** - Base abstract class for all notifications
2. **NotificationTypeEnum** - Defines all notification types in the system
3. **NotificationCategoryEnum** - Defines filterable categories (Orders, Financial, System)
4. **Events & Listeners** - Trigger notifications automatically
5. **FcmChannel** - Custom channel for push notifications

## Notification Structure

Every notification MUST follow this unified structure:

```php
[
    'title' => [
        'ar' => 'العنوان بالعربية',
        'en' => 'Title in English',
    ],
    'body' => [
        'ar' => 'المحتوى بالعربية',
        'en' => 'Body content in English',
    ],
    'notify_type' => NotificationTypeEnum::SERVICE_ORDER->value,
    'notify_id'   => $entityId, // ID of the related entity (order, ad, etc.)
]
```

### Optional Fields

```php
[
    'sender_id' => $userId,  // For notifications sent from one user to another
    'icon' => 'url-to-icon', // Custom icon (optional)
    // ... any additional data
]
```

## Creating a New Notification

### Step 1: Create the Notification Class

```php
<?php

namespace App\Notifications\ServiceOrders;

use App\Enums\NotificationTypeEnum;
use App\Models\ServiceOrder;
use App\Notifications\AppNotification;

/**
 * Sent to the client when provider completes the service order.
 */
class ServiceOrderCompletedNotification extends AppNotification
{
    public function __construct(private readonly ServiceOrder $order) {}

    public function toArray(mixed $notifiable): array
    {
        return [
            'title' => [
                'ar' => 'تم إكمال الطلب',
                'en' => 'Order Completed',
            ],
            'body' => [
                'ar' => "تم إكمال طلبك رقم #{$this->order->id}. يرجى المراجعة والتأكيد.",
                'en' => "Your order #{$this->order->id} has been completed. Please review and confirm.",
            ],
            'notify_type' => NotificationTypeEnum::ORDER_COMPLETED->value,
            'notify_id'   => $this->order->id,
        ];
    }
}
```

### Step 2: Create or Use an Event

```php
<?php

namespace App\Events\ServiceOrders;

use App\Models\ServiceOrder;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class ServiceOrderCompleted
{
    use Dispatchable, SerializesModels;

    public function __construct(public readonly ServiceOrder $order) {}
}
```

### Step 3: Create a Listener

```php
<?php

namespace App\Listeners\ServiceOrders;

use App\Events\ServiceOrders\ServiceOrderCompleted;
use App\Notifications\ServiceOrders\ServiceOrderCompletedNotification;

class SendServiceOrderCompletedNotification
{
    public function handle(ServiceOrderCompleted $event): void
    {
        $order = $event->order;
        $client = $order->client;

        // Send notification to the client
        $client->notify(new ServiceOrderCompletedNotification($order));
    }
}
```

### Step 4: Register the Listener

In `app/Providers/EventServiceProvider.php`:

```php
protected $listen = [
    ServiceOrderCompleted::class => [
        SendServiceOrderCompletedNotification::class,
    ],
];
```

### Step 5: Dispatch the Event

In your service or controller:

```php
use App\Events\ServiceOrders\ServiceOrderCompleted;

// When the order is marked as completed
event(new ServiceOrderCompleted($order));
```

## Notification Types & Categories

### Available Types

See `App\Enums\NotificationTypeEnum` for all available types:

- **Orders:** `SERVICE_ORDER`, `SERVICE_OFFER`, `URGENT_ORDER`, `ORDER_STATUS`, etc.
- **Financial:** `PAYMENT`, `WITHDRAWAL`, `WALLET`, `COMMISSION`, `REFUND`
- **System:** `SYSTEM`, `ACCOUNT`, `PROVIDER_STATUS`, `VERIFICATION`, etc.

### Categories (For Filtering)

Users can filter notifications by these categories:

1. **الكل (All)** - `all` - No filtering
2. **الطلبات (Orders)** - `orders` - All order-related notifications
3. **المالية (Financial)** - `financial` - All financial notifications
4. **النظام (System)** - `system` - System, account, and other notifications

## API Endpoints

### List Notifications

```http
GET /api/v1/{user_type}/notifications
```

**Query Parameters:**
- `category` (optional): `all`, `orders`, `financial`, `system`
- `per_page` (optional): Number of items per page (1-100, default: 15)

**Response:**
```json
{
  "status": "success",
  "message": "",
  "unread_count": 5,
  "data": [
    {
      "id": "9d3c5b89-...",
      "title": "طلب خدمة جديد",
      "body": "تم تقديم طلب خدمة جديد",
      "notify_type": "service_order",
      "notify_id": 123,
      "created_at": 1704067200,
      "read_at": null,
      "is_readed": false,
      "created_time": "منذ 5 دقائق"
    }
  ],
  "meta": { ... },
  "links": { ... },
  "filter": {
    "current_category": "orders",
    "available_categories": [
      {
        "value": "all",
        "label_ar": "الكل",
        "label_en": "All"
      },
      // ...
    ]
  }
}
```

### Show Notification

```http
GET /api/v1/{user_type}/notifications/{id}
```

Marks the notification as read automatically.

### Mark as Read

```http
POST /api/v1/{user_type}/notifications/mark-as-read
POST /api/v1/{user_type}/notifications/{id}/mark-as-read
```

Mark all or specific notification as read.

### Delete Notifications

```http
DELETE /api/v1/{user_type}/notifications
DELETE /api/v1/{user_type}/notifications/{id}
POST /api/v1/{user_type}/notifications/delete-multiple
```

## Push Notifications (FCM)

### Routing Logic

Defined in `AppNotification::via()`:

- **Dashboard users** (admin, super_admin, manager): Always receive database + FCM
- **Mobile users** (client, provider): Always database, FCM only if `is_notify = true`

### FCM Configuration

Users can enable/disable push notifications from their profile:

```php
$user->is_notify = true; // Enable push notifications
$user->save();
```

## Best Practices

### 1. Always Use Enums for Types

❌ **Wrong:**
```php
'notify_type' => 'service_order',
```

✅ **Correct:**
```php
'notify_type' => NotificationTypeEnum::SERVICE_ORDER->value,
```

### 2. Use Events & Listeners

Don't call `->notify()` directly in controllers. Use events:

❌ **Wrong:**
```php
public function approveAd($id)
{
    $ad = Ad::find($id);
    $ad->update(['status' => 'approved']);
    $ad->owner->notify(new AdApprovedNotification($ad)); // Direct call
}
```

✅ **Correct:**
```php
public function approveAd($id)
{
    $ad = Ad::find($id);
    $ad->update(['status' => 'approved']);
    event(new AdApproved($ad)); // Event-driven
}
```

### 3. Bilingual Content

Always provide both Arabic and English:

```php
'title' => [
    'ar' => 'النص العربي',
    'en' => 'English Text',
],
```

### 4. Gender-Aware Content (Optional)

For gender-specific messages:

```php
'body' => [
    'ar' => [
        'male' => 'تم قبول طلبك يا سيد أحمد',
        'female' => 'تم قبول طلبك يا آنسة فاطمة',
    ],
    'en' => 'Your request has been accepted',
],
```

### 5. Include Related Entity ID

Always include the ID of the related entity:

```php
'notify_id' => $order->id,
'notify_type' => NotificationTypeEnum::SERVICE_ORDER->value,
```

This allows the mobile app to navigate to the correct screen when tapped.

## Testing Notifications

### Test a Single Notification

```php
use App\Notifications\ServiceOrders\NewServiceOrderNotification;

$user = User::find(1);
$order = ServiceOrder::find(123);

$user->notify(new NewServiceOrderNotification($order));
```

### Test via Event

```php
use App\Events\ServiceOrders\ServiceOrderCreated;

$order = ServiceOrder::find(123);
event(new ServiceOrderCreated($order));
```

### Test FCM

```bash
php artisan fcm:test {userId}
```

## Notification Delivery Channels

### Database Channel

All notifications are stored in the `notifications` table (Laravel default).

### FCM Channel

Custom channel implemented in `App\Channels\FcmChannel`.

Sends push notifications to mobile devices via Firebase Cloud Messaging.

## Common Use Cases

### 1. Notify Multiple Users

```php
$users = User::where('user_type', 'admin')->get();

foreach ($users as $user) {
    $user->notify(new AdReportedNotification($report));
}
```

### 2. Notify Based on Conditions

```php
$providers = User::where('user_type', 'provider')
    ->where('subcategory_id', $order->service->subcategory_id)
    ->where('is_active', true)
    ->get();

foreach ($providers as $provider) {
    $provider->notify(new NewServiceOrderNotification($order));
}
```

### 3. Broadcast Notification

```php
$users = User::where('is_active', true)->get();

foreach ($users as $user) {
    $user->notify(new SystemAnnouncementNotification($announcement));
}
```

## Troubleshooting

### Notifications Not Appearing

1. Check user's `is_notify` flag
2. Verify FCM token is stored
3. Check event listener is registered
4. Verify notification type enum value is correct

### Filter Not Working

1. Ensure `notify_type` uses enum value
2. Check category enum mapping
3. Verify JSON structure in database

### Push Notifications Not Delivered

1. Check FCM credentials in `.env`
2. Verify device token is valid
3. Check `is_notify` flag for mobile users
4. Review FCM channel logs

## Migration Guide

If you have existing notifications not using the new enum system:

```php
use App\Enums\NotificationTypeEnum;

// Update old notifications
DB::table('notifications')
    ->where('data->notify_type', 'service_order')
    ->update([
        'data->notify_type' => NotificationTypeEnum::SERVICE_ORDER->value
    ]);
```

## Summary

✅ **DO:**
- Use `AppNotification` as base class
- Use `NotificationTypeEnum` for types
- Provide bilingual content
- Use events & listeners
- Include `notify_id` and `notify_type`

❌ **DON'T:**
- Hardcode notification types
- Call `->notify()` directly in controllers
- Mix English and Arabic in same string
- Forget to register listeners

---

**Version:** 1.0  
**Last Updated:** 2026-09-07
