# How Media Works in Your Application

## 🎯 Key Concept

**Media is automatically attached to models when you save them with media IDs in the request.**

You don't manually attach media - the `UploadMediaObserver` does it automatically!

## 📋 The Pattern

### 1. Model Setup (Profile Model)

```php
class Profile extends Model
{
    use MediaTrait;  // ← This enables automatic media handling
    
    protected array $mediaColumns = [
        'logo' => [
            'is_single'  => true,      // Only one logo
            'type'       => 'image',
            'option'     => 'logo',    // Key identifier
            'default'    => null,
        ],
        'commercial_register_file' => [
            'is_single'  => true,      // Only one file
            'type'       => 'file',
            'option'     => 'commercial_register_file',
            'default'    => null,
        ],
    ];
}
```

### 2. How UploadMediaObserver Works

When you call `$profile->update($data)` or `$profile->save()`:

```php
// UploadMediaObserver automatically:
// 1. Checks if request has 'logo' or 'commercial_register_file'
// 2. If is_single = true, deletes old media
// 3. Attaches new media to the model
// 4. Sets model_id, model_type, option, is_attached
```

**The magic happens in `UploadMediaObserver::saved()`:**

```php
public function saved(Model $model): void
{
    $mediaColumns = $model->mediaColumns;
    $mediaInput = request()->only(array_keys($mediaColumns));
    
    foreach ($mediaInput as $option => $value) {
        $isSingle = $mediaColumns[$option]['is_single'];
        
        if ($isSingle) {
            // Delete old media
            Media::where('model_type', get_class($model))
                ->where('model_id', $model->id)
                ->where('option', $option)
                ->delete();
        }
        
        // Attach new media
        $media = Media::find($value);
        $media->update([
            'model_id'    => $model->id,
            'model_type'  => get_class($model),
            'is_attached' => true,
            'option'      => $option,
        ]);
    }
}
```

## 🔄 Complete Flow

### Step 1: Upload File
```bash
POST /api/media
file: logo.jpg
model: Profile
media_type: image
```

**Response:**
```json
{
  "id": "abc123-media-id"
}
```

### Step 2: Update Profile with Media ID

**Option A: Direct Profile Update**
```php
// In ProfileController
$profile->update([
    'logo' => 'abc123-media-id',  // ← Media ID in request
    'commercial_register_number' => 'CR-123',
]);

// UploadMediaObserver automatically:
// - Deletes old logo media
// - Attaches new logo media to profile
```

**Option B: Via Profile Update Request (Our Case)**
```php
// In ProfileUpdateRequest::approve()
request()->merge(['logo' => $this->profile_data['logo']]);
$profile->update($updateData);

// UploadMediaObserver sees 'logo' in request
// Automatically attaches it to profile
```

### Step 3: Access Media
```php
$profile->logo;
// Returns:
// [
//   'id' => 'abc123-media-id',
//   'path' => 'https://domain.com/storage/images/logo.jpg',
//   'type' => 'image',
//   'option' => 'logo'
// ]
```

## 🎨 How Our Profile Update Request Works

### When Vendor Creates Request

```php
// Vendor sends:
{
  "logo": "abc123-media-id",
  "commercial_register_file": "def456-media-id",
  "ar": {"name": "...", "description": "..."},
  "en": {"name": "...", "description": "..."}
}

// We store in profile_data JSON:
{
  "logo": "abc123-media-id",
  "commercial_register_file": "def456-media-id",
  "commercial_register_number": "CR-123",
  "translations": {...}
}
```

### When Admin Approves

```php
public function approve(): void
{
    // 1. Merge media IDs into request
    request()->merge([
        'logo' => $this->profile_data['logo'],
        'commercial_register_file' => $this->profile_data['commercial_register_file']
    ]);
    
    // 2. Update profile
    $profile->update([
        'commercial_register_number' => $this->profile_data['commercial_register_number']
    ]);
    
    // 3. UploadMediaObserver automatically:
    //    - Sees 'logo' and 'commercial_register_file' in request
    //    - Deletes old media (because is_single = true)
    //    - Attaches new media to profile
    
    // 4. Update translations
    foreach ($this->profile_data['translations'] as $locale => $translation) {
        $profile->translateOrNew($locale)->name = $translation['name'];
        $profile->translateOrNew($locale)->description = $translation['description'];
    }
    $profile->save();
}
```

## ✅ Why This Approach is Better

### ❌ Manual Approach (Complex)
```php
// Delete old media
$profile->media()->where('option', 'logo')->delete();

// Find new media
$media = Media::find($mediaId);

// Manually attach
$media->update([
    'model_id' => $profile->id,
    'model_type' => get_class($profile),
    'is_attached' => true,
    'option' => 'logo',
]);
```

### ✅ Automatic Approach (Simple)
```php
// Just merge media ID into request
request()->merge(['logo' => $mediaId]);

// Update model - Observer handles everything!
$profile->update($data);
```

## 🔍 How to Debug

### Check if Media is Attached
```php
$profile->media()->where('option', 'logo')->first();
// Should return the media record with model_id = profile->id
```

### Check Request Data
```php
// In approve() method
dd(request()->all());
// Should show: ['logo' => 'abc123', 'commercial_register_file' => 'def456']
```

### Check Media Columns
```php
dd($profile->mediaColumns);
// Should show the mediaColumns array
```

## 📝 Important Rules

1. **Media ID must be in request** - `request()->merge()` puts it there
2. **Model must use MediaTrait** - Profile already does
3. **mediaColumns must be defined** - Profile already has it
4. **Observer is automatically registered** - Via `bootMediaTrait()`
5. **is_single = true** - Old media is deleted automatically

## 🎯 Summary

**You don't manually attach media!**

Just:
1. Upload file → Get media ID
2. Put media ID in request → `request()->merge(['logo' => $id])`
3. Save/update model → `$profile->update($data)`
4. Observer handles everything automatically! ✨

The `UploadMediaObserver` is like a magic helper that watches every model save and automatically manages media attachments for you.
