# مرجع API — تطبيق Flutter

**Base URL:** `https://pod.sayedkhattab.com`

---

## 1. المصادقة — `/api/app/auth`

### POST `/register`

**Body (JSON):**

```json
{
  "name": "أحمد محمد",
  "email": "ahmed@example.com",
  "phone": "01012345678",
  "password": "secret123"
}
```

**Response 201:**

```json
{
  "token": "eyJ...",
  "user": {
    "id": 1,
    "name": "أحمد محمد",
    "email": "ahmed@example.com",
    "phone": "01012345678"
  }
}
```

### POST `/login`

```json
{ "email": "ahmed@example.com", "password": "secret123" }
```

**Response 200:** نفس شكل التسجيل.

### GET `/me` 🔒

**Response 200:**

```json
{
  "id": 1,
  "name": "أحمد محمد",
  "email": "ahmed@example.com",
  "phone": "01012345678",
  "created_at": "2026-05-30T10:00:00.000Z"
}
```

### PATCH `/profile` 🔒

```json
{ "name": "أحمد", "phone": "01099998888" }
```

### PATCH `/password` 🔒

```json
{
  "current_password": "secret123",
  "new_password": "newpass456"
}
```

---

## 2. الصفحة الرئيسية — `GET /api/app/home`

**Response 200:**

```json
{
  "settings": {
    "store_name_ar": "أركان",
    "store_name_en": "Arkan",
    "currency": "EGP",
    "country": "EG",
    "payment_method": "cod",
    "cod_label_ar": "الدفع عند الاستلام",
    "min_order_amount": 0,
    "default_eta_days": 2,
    "support_phone": "",
    "support_whatsapp": "",
    "store_description_ar": "...",
    "orders_accepting": true,
    "map_default_lat": 30.0444,
    "map_default_lng": 31.2357,
    "map_default_zoom": 6
  },
  "banners": [
    {
      "id": 1,
      "title_ar": "عرض خاص",
      "title_en": null,
      "subtitle_ar": null,
      "subtitle_en": null,
      "image_url": "/api/uploads/banners/xxx.jpg",
      "link_type": "product",
      "link_value": "5",
      "sort_order": 0
    }
  ]
}
```

**link_type:** `none` | `product` | `category` | `url`

---

## 3. الكatalog — `/api/app/catalog`

### GET `/categories`

```json
{
  "data": [
    {
      "id": 1,
      "name_ar": "تيشيرتات",
      "name_en": "T-Shirts",
      "slug": "t-shirts",
      "image_url": "/api/uploads/products/xxx.jpg",
      "sort_order": 0
    }
  ]
}
```

### GET `/products`

**Query:** `category_id`, `search`

```json
{
  "data": [
    {
      "id": 1,
      "category_id": 1,
      "name_ar": "تيشيرت قطن",
      "name_en": null,
      "slug": "cotton-tee",
      "description_ar": "...",
      "base_price": 250,
      "from_price": 250,
      "image_url": "/api/uploads/products/xxx.jpg",
      "category_name": "تيشيرتات"
    }
  ]
}
```

### GET `/products/:id`

```json
{
  "id": 1,
  "name_ar": "تيشيرت قطن",
  "base_price": 250,
  "print_area": { "width": 3000, "height": 3500 },
  "variants": [
    {
      "id": 1,
      "sku": "TEE-M-WHT",
      "size": "M",
      "color": "أبيض",
      "color_hex": "#FFFFFF",
      "extra_price": 0,
      "stock": 50
    }
  ],
  "print_faces": [
    {
      "id": 1,
      "face_key": "front",
      "label_ar": "أمام",
      "label_en": "Front",
      "extra_price": 0,
      "area": { "x": 0.2, "y": 0.15, "width": 0.6, "height": 0.5 },
      "sort_order": 0,
      "is_active": true
    }
  ]
}
```

> `area` إحداثيات نسبية (0–1) داخل مساحة الطباعة.

---

## 4. معرض التصاميم — `GET /api/design-gallery/browse`

**Query:** `category`, `search`

**Categories:** `general`, `sports`, `quotes`, `anime`, `logos`, `seasonal`, `kids`, `patterns`

```json
{
  "data": [
    {
      "id": 1,
      "title_ar": "تصميم رياضي",
      "title_en": null,
      "category": "sports",
      "file_url": "/api/uploads/designs/gallery/xxx.png",
      "preview_url": "/api/uploads/designs/gallery/xxx.png",
      "sort_order": 0
    }
  ]
}
```

---

## 5. مناطق التوصيل — `/api/app/zones`

### GET `/`

```json
{
  "data": [
    {
      "id": 1,
      "name_ar": "القاهرة",
      "name_en": "Cairo",
      "polygon_geojson": { "type": "Polygon", "coordinates": [[[...]]] },
      "delivery_fee": 35,
      "min_order_amount": 200,
      "eta_days": 2,
      "color": "#2563eb"
    }
  ]
}
```

### POST `/check`

```json
{ "lat": 30.0444, "lng": 31.2357 }
```

**Response (مغطى):**

```json
{
  "covered": true,
  "zone": {
    "id": 1,
    "name_ar": "القاهرة",
    "delivery_fee": 35,
    "min_order_amount": 200,
    "eta_days": 2,
    "color": "#2563eb"
  }
}
```

**Response (غير مغطى):**

```json
{
  "covered": false,
  "message": "الموقع خارج مناطق التوصيل المتاحة"
}
```

---

## 6. الكوبونات — `POST /api/app/coupons/validate`

```json
{ "code": "WELCOME10", "subtotal": 500 }
```

**Response 200:**

```json
{
  "valid": true,
  "coupon": { "id": 1, "code": "WELCOME10", "type": "percent", "value": 10 },
  "discount": 50,
  "free_shipping": false
}
```

**أنواع الكوبون:** `percent` | `fixed` | `free_shipping`

---

## 7. رفع التصاميم — `POST /api/app/uploads/design` 🔒

**Content-Type:** `multipart/form-data`

| Field | Type |
|-------|------|
| `image` | file (jpg, png, gif, webp, svg — max 10MB) |

**Response 201:**

```json
{
  "url": "/api/uploads/designs/users/1748600000-abc123.png",
  "preview_url": "/api/uploads/designs/users/1748600000-abc123.png",
  "filename": "1748600000-abc123.png",
  "size": 245000
}
```

### POST `/api/app/designs` 🔒

```json
{
  "title": "شعاري",
  "file_url": "/api/uploads/designs/users/1748600000-abc123.png",
  "preview_url": "/api/uploads/designs/users/1748600000-abc123.png"
}
```

**Response 201:** التصميم بحالة `pending` — يحتاج موافقة الإدارة قبل استخدامه في الطلب.

### GET `/api/app/designs` 🔒

**Query:** `status` = `pending` | `approved` | `rejected`

---

## 8. الدفع والطلب — `/api/app/checkout`

### POST `/quote` 🔒

```json
{
  "items": [
    {
      "product_id": 1,
      "variant_id": 2,
      "quantity": 1,
      "design_id": 5,
      "gallery_design_id": null,
      "print_config": {
        "faces": [
          { "face_key": "front", "scale": 1, "offset_x": 0, "offset_y": 0 }
        ]
      }
    }
  ],
  "lat": 30.0444,
  "lng": 31.2357,
  "zone_id": 1,
  "coupon_code": "WELCOME10"
}
```

**قواعد العنصر:**
- `design_id` **أو** `gallery_design_id` مطلوب (يمكن أحدهما)
- `design_id` يجب أن يكون `approved` ويخص المستخدم
- `gallery_design_id` من المعرض النشط
- `variant_id` مطلوب إذا كان للمنتج variants

**Response 200:**

```json
{
  "subtotal": 250,
  "discount": 25,
  "shipping_fee": 35,
  "total": 260,
  "currency": "EGP",
  "coupon": { "id": 1, "code": "WELCOME10", "type": "percent", "value": 10 },
  "zone": { "id": 1, "name_ar": "القاهرة", "delivery_fee": 35, "eta_days": 2 },
  "items": [...],
  "payment_method": "cod",
  "cod_label_ar": "الدفع عند الاستلام"
}
```

### POST `/` 🔒 (إنشاء الطلب)

نفس body الـ quote + بيانات الشحن:

```json
{
  "items": [...],
  "lat": 30.0444,
  "lng": 31.2357,
  "shipping_name": "أحمد محمد",
  "shipping_phone": "01012345678",
  "shipping_address": "15 شارع...، المعادي، القاهرة",
  "notes": "اتصل قبل التوصيل",
  "coupon_code": "WELCOME10"
}
```

**Response 201:**

```json
{
  "message": "تم إنشاء الطلب بنجاح",
  "order_id": 42,
  "order_number": "ARK-20260530-A1B2",
  "total": 260
}
```

---

## 9. الطلبات — `/api/app/orders` 🔒

### GET `/`

```json
{
  "data": [
    {
      "id": 42,
      "order_number": "ARK-20260530-A1B2",
      "status": "pending",
      "status_label": "قيد الانتظار",
      "subtotal": 250,
      "shipping_fee": 35,
      "total": 260,
      "payment_method": "cod",
      "cod_collected": 0,
      "zone_name": "القاهرة",
      "items_count": 1,
      "created_at": "..."
    }
  ]
}
```

**حالات الطلب:**

| status | status_label |
|--------|----------------|
| `pending` | قيد الانتظار |
| `confirmed` | مؤكد |
| `printing` | قيد الطباعة |
| `out_for_delivery` | في الطريق |
| `delivered` | تم التسليم |
| `cancelled` | ملغي |

### GET `/:id`

يتضمن `items[]` و `timeline[]`.

### PATCH `/:id/cancel`

فقط عندما `status === pending`.

---

## 10. ملاحظات تقنية

- جميع الأسعار `number` (Decimal)
- التواريخ ISO 8601
- `print_config` JSON حر — يُحفظ كما يرسله التطبيق (موضع التصميم على كل face)
- السعر = `base_price + variant.extra_price + sum(face.extra_price للوجوه المستخدمة)`
