# Media Library

The media library provides centralized management of uploaded files (images, documents) for stores. Each store has their own isolated media storage.

## Overview

- **Storage Location**: `uploads/stores/{store_id}/{folder}/`
- **Supported Types**: Images (JPG, PNG, GIF, WebP), Documents (PDF)
- **Max File Size**: 10MB per file
- **Automatic Thumbnails**: Generated for images (200x200px)

## API Endpoints

### Admin Media Management

Admins can manage media for any store:

```
GET    /api/v1/admin/media/stores/{store_id}           # List store's media
POST   /api/v1/admin/media/stores/{store_id}/upload    # Upload file
GET    /api/v1/admin/media/stores/{store_id}/{id}      # Get media details
DELETE /api/v1/admin/media/stores/{store_id}/{id}      # Delete media
```

### Query Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `skip` | int | Pagination offset (default: 0) |
| `limit` | int | Items per page (default: 100, max: 1000) |
| `media_type` | string | Filter by type: `image`, `video`, `document` |
| `folder` | string | Filter by folder: `products`, `general`, etc. |
| `search` | string | Search by filename |

### Upload Response

```json
{
  "success": true,
  "message": "File uploaded successfully",
  "media": {
    "id": 1,
    "filename": "product-image.jpg",
    "file_url": "/uploads/stores/1/products/abc123.jpg",
    "url": "/uploads/stores/1/products/abc123.jpg",
    "thumbnail_url": "/uploads/stores/1/thumbnails/thumb_abc123.jpg",
    "media_type": "image",
    "file_size": 245760,
    "width": 1200,
    "height": 800
  }
}
```

## Media Picker Component

A reusable Alpine.js component for selecting images from the media library.

### Usage in Templates

```jinja2
{% from 'shared/macros/modals.html' import media_picker_modal %}

{# Single image selection #}
{{ media_picker_modal(
    id='media-picker-main',
    show_var='showMediaPicker',
    store_id_var='storeId',
    title='Select Image'
) }}

{# Multiple image selection #}
{{ media_picker_modal(
    id='media-picker-additional',
    show_var='showMediaPickerAdditional',
    store_id_var='storeId',
    multi_select=true,
    title='Select Additional Images'
) }}
```

### JavaScript Integration

Include the media picker mixin in your Alpine.js component:

```javascript
function myComponent() {
    return {
        ...data(),

        // Include media picker functionality
        ...mediaPickerMixin(() => this.storeId, false),

        storeId: null,

        // Override to handle selected image
        setMainImage(media) {
            this.form.image_url = media.url;
        },

        // Override for multiple images
        addAdditionalImages(mediaList) {
            const urls = mediaList.map(m => m.url);
            this.form.additional_images.push(...urls);
        }
    };
}
```

### Media Picker Mixin API

| Property/Method | Description |
|-----------------|-------------|
| `showMediaPicker` | Boolean to show/hide main image picker modal |
| `showMediaPickerAdditional` | Boolean to show/hide additional images picker |
| `mediaPickerState` | Object containing loading, media array, selected items |
| `openMediaPickerMain()` | Open picker for main image |
| `openMediaPickerAdditional()` | Open picker for additional images |
| `loadMediaLibrary()` | Fetch media from API |
| `uploadMediaFile(event)` | Handle file upload |
| `toggleMediaSelection(media)` | Select/deselect a media item |
| `confirmMediaSelection()` | Confirm selection and call callbacks |
| `setMainImage(media)` | Override to handle main image selection |
| `addAdditionalImages(mediaList)` | Override to handle multiple selections |

## File Storage

### Directory Structure

```
uploads/
└── stores/
    └── {store_id}/
        ├── products/         # Product images
        ├── general/          # General uploads
        └── thumbnails/       # Auto-generated thumbnails
```

### URL Paths

Files are served from `/uploads/` path:
- Full image: `/uploads/stores/1/products/image.jpg`
- Thumbnail: `/uploads/stores/1/thumbnails/thumb_image.jpg`

## Database Model

```python
class MediaFile(Base):
    id: int
    store_id: int
    filename: str              # Stored filename (UUID-based)
    original_filename: str     # Original upload name
    file_path: str            # Relative path from uploads/
    thumbnail_path: str       # Thumbnail relative path
    media_type: str           # image, video, document
    mime_type: str            # image/jpeg, etc.
    file_size: int            # Bytes
    width: int                # Image width
    height: int               # Image height
    folder: str               # products, general, etc.
```

## Product Images

Products support both a main image and additional images:

```python
class Product(Base):
    primary_image_url: str           # Main product image
    additional_images: list[str]     # Array of additional image URLs
```

### In Product Forms

The product create/edit forms include:
1. **Main Image**: Single image with preview and media picker
2. **Additional Images**: Grid of images with add/remove functionality

Both support:
- Browsing the store's media library
- Uploading new images directly
- Entering external URLs manually
