# Enums Usage Guide

This document explains how to use the enum system for storing and managing hardcoded values in the Laravel backend.

## Overview

We've created PHP 8.1+ enums to replace hardcoded arrays in the frontend. This provides:
- Type safety
- Better performance (no database queries)
- Centralized management
- Easy API exposure

## Available Enums

### 1. PassportStatus
- `has` - 已有護照
- `agency` - 無護照，請旅行社代辦
- `self` - 無護照，自行辦理

### 2. MealRequirements
- `none` - 無特殊餐食限制
- `vegetarian` - 全素食
- `lacto-ovo` - 蛋奶素

### 3. FoodRestrictions
- `牛`, `羊`, `豬`, `雞`, `鴨`, `魚`, `海鮮`

### 4. TicketHandling
- `none` - 無特殊需求
- `premium` - 加價預訂個人去/回程機票
- `individual` - 不團進團出，機票自理

### 5. ClassPreference
- `none` - 無特殊
- `premium` - 豪經艙
- `business` - 商務艙

### 6. Nationality
- 35+ countries including `TW`, `CN`, `HK`, `US`, `JP`, etc.

### 7. BedType
- `none` - 無特殊需求
- `twin` - 兩小床
- `double` - 一大床
- `single` - 單人配房

### 8. SeatPreference
- `none` - 無特殊
- `window` - 靠窗
- `aisle` - 靠走道

### 9. PaymentMethod
- `creditCard` - 信用卡付款
- `bankTransfer` - 銀行轉帳
- `cash` - 現金付款

### 10. TravelPurpose
- `honeymoon` - 蜜月
- `family` - 家庭旅遊
- `other` - 其他

### 11. MarketingSource
- `socialMedia` - 粉絲專頁（FB/IG/thread/Dcard）
- `lineAds` - LINE旅遊 / FB廣告
- `googleWebsite` - Google關鍵字 / 官方網站
- `lineGroup` - LINE蜜月群組
- `referral` - 親友介紹
- `other` - 其他

## Folder Structure

All booking-related enums are organized under `app/Enums/Booking/`:

```
app/Enums/Booking/
├── PassportStatus.php
├── MealRequirements.php
├── FoodRestrictions.php
├── TicketHandling.php
├── ClassPreference.php
├── Nationality.php
├── BedType.php
├── SeatPreference.php
├── PaymentMethod.php
├── TravelPurpose.php
└── MarketingSource.php
```

## Usage in Models

The enums are automatically cast in the models:

```php
// In TravelerPassport model
use App\Enums\Booking\PassportStatus;

protected $casts = [
    'passport_status' => PassportStatus::class,
];

// Usage
$passport = TravelerPassport::find(1);
echo $passport->passport_status->label(); // "已有護照"
echo $passport->passport_status->value; // "has"
```

## API Endpoints

### Get All Options
```
GET /api/options
```

### Get Specific Options
```
GET /api/options/passport-status
GET /api/options/meal-requirements
GET /api/options/food-restrictions
GET /api/options/ticket-handling
GET /api/options/class-preference
GET /api/options/nationality
GET /api/options/bed-type
GET /api/options/seat-preference
GET /api/options/payment-method
GET /api/options/travel-purpose
GET /api/options/marketing-source
```

## Frontend Integration

Replace your hardcoded arrays with API calls:

```javascript
// Before
export const PASSPORT_STATUS_OPTIONS = [
  { value: 'has', label: '已有護照' },
  { value: 'agency', label: '無護照，請旅行社代辦' },
  { value: 'self', label: '無護照，自行辦理' }
] as const;

// After
const [passportStatusOptions, setPassportStatusOptions] = useState([]);

useEffect(() => {
  fetch('/api/options/passport-status')
    .then(res => res.json())
    .then(data => setPassportStatusOptions(data));
}, []);
```

## Benefits

1. **Type Safety**: PHP enums provide compile-time type checking
2. **Performance**: No database queries needed for options
3. **Maintainability**: All options centralized in one place
4. **Consistency**: Same data structure across frontend and backend
5. **API Ready**: Easy to expose as REST endpoints
6. **Validation**: Automatic validation when using enum values

## Migration from Hardcoded Values

1. Update your frontend to fetch options from the API
2. The backend will automatically handle enum casting
3. Existing data will continue to work (string values are automatically converted to enum instances)
4. New data will be validated against enum values

## Adding New Options

To add new options to an enum:

1. Add the new case to the enum
2. Add the corresponding label in the `label()` method
3. The `options()` method will automatically include the new option
4. No database migration needed

Example:
```php
// In app/Enums/Booking/PassportStatus.php
namespace App\Enums\Booking;

enum PassportStatus: string
{
    case HAS = 'has';
    case AGENCY = 'agency';
    case SELF = 'self';
    case NEW_OPTION = 'new_option'; // Add this

    public function label(): string
    {
        return match($this) {
            self::HAS => '已有護照',
            self::AGENCY => '無護照，請旅行社代辦',
            self::SELF => '無護照，自行辦理',
            self::NEW_OPTION => '新選項', // Add this
        };
    }
}
``` 