# Frontend Integration Guide - Coupon System

## Overview
This guide helps frontend developers integrate the new coupon system with support for:
- General coupons
- Vendor-specific coupons
- Category-specific coupons
- Brand-specific coupons
- First-time order coupons

## Admin Panel Integration

### 1. Coupon Form Fields

#### Basic Fields (Always Required)
```javascript
{
  code: string,              // Coupon code (e.g., "SUMMER20")
  type: "percentage" | "fixed",
  value: number,             // Percentage (1-100) or fixed amount
  client_type: "normal" | "premium",
  start_at: date,            // Format: YYYY-MM-DD
  end_at: date,              // Format: YYYY-MM-DD
  limit: number,             // Total usage limit (min: 2)
  limit_for_user: number,    // Per-user limit (min: 1, max: limit)
  is_active: boolean,
  min_order_total: number,   // Optional
  max_order_total: number,   // Optional
  
  // Translations
  en: {
    name: string,
    description: string
  },
  ar: {
    name: string,
    description: string
  }
}
```

#### New Field: apply_on (Required)
```javascript
apply_on: "general" | "vendor" | "category" | "brand" | "first_order"
```

#### Conditional Fields (Based on apply_on)
```javascript
// Single polymorphic field instead of separate vendor_id, category_id, brand_id
applicable_id: number  // Required when apply_on is vendor/category/brand

// The applicable_type is automatically set by the backend based on apply_on:
// - apply_on === "vendor" → applicable_type = "App\Models\User"
// - apply_on === "category" → applicable_type = "App\Models\Category"  
// - apply_on === "brand" → applicable_type = "App\Models\Brand"
```

### 2. Form UI Logic

```javascript
// Example React/Vue logic
const [applyOn, setApplyOn] = useState('general');

// Show/hide conditional fields
const showVendorField = applyOn === 'vendor';
const showCategoryField = applyOn === 'category';
const showBrandField = applyOn === 'brand';
const isFirstOrder = applyOn === 'first_order';

// Form validation
const validateForm = () => {
  const requiresApplicableId = ['vendor', 'category', 'brand'].includes(applyOn);
  
  if (requiresApplicableId && !formData.applicable_id) {
    return `Please select a ${applyOn}`;
  }
  
  return null;
};
```

### 3. Coupon List Display

```javascript
// Response from GET /api/dashboard/admin/coupons
{
  "status": "success",
  "data": {
    "coupons": [
      {
        "id": 1,
        "code": "VENDOR20",
        "apply_on": "vendor",
        "type": "percentage",
        "value": 20,
        "is_first_order": false,
        
        // Polymorphic fields
        "applicable_id": 5,
        "applicable_type": "App\\Models\\User",
        "applicable_name": "Store Name"
      }
    ]
  }
}
```

#### Display Logic
```javascript
const getCouponTypeLabel = (coupon) => {
  switch (coupon.apply_on) {
    case 'general':
      return 'General Coupon';
    case 'vendor':
    case 'category':
    case 'brand':
      return `${coupon.apply_on.charAt(0).toUpperCase() + coupon.apply_on.slice(1)}: ${coupon.applicable_name}`;
    case 'first_order':
      return 'First Order Only';
    default:
      return 'Unknown';
  }
};
```

## Mobile App Integration

### 1. Display Available Coupons

```javascript
// GET /api/app/coupons
const response = await fetch('/api/app/coupons?per_page=10');
const data = await response.json();

// Response structure
{
  "status": "success",
  "data": [
    {
      "id": 1,
      "code": "WELCOME10",
      "name": "Welcome Discount",
      "description": "Get 10% off on your first order",
      "apply_on": "first_order",
      "type": "percentage",
      "value": 10,
      "is_first_order": true,
      "applicable_id": null,
      "applicable_type": null,
      "applicable_name": null
    }
  ]
}
```

#### Display Coupon Card
```javascript
const CouponCard = ({ coupon }) => {
  const getApplicabilityText = () => {
    switch (coupon.apply_on) {
      case 'general':
        return 'Valid on all products';
      case 'vendor':
        return `Valid only at ${coupon.applicable_name}`;
      case 'category':
        return `Valid only for ${coupon.applicable_name}`;
      case 'brand':
        return `Valid only for ${coupon.applicable_name} products`;
      case 'first_order':
        return 'Valid for first order only';
      default:
        return '';
    }
  };

  return (
    <div className="coupon-card">
      <h3>{coupon.name}</h3>
      <p>{coupon.description}</p>
      <div className="coupon-code">{coupon.code}</div>
      <div className="discount">
        {coupon.type === 'percentage' 
          ? `${coupon.value}% OFF` 
          : `$${coupon.value} OFF`}
      </div>
      <div className="applicability">{getApplicabilityText()}</div>
    </div>
  );
};
```

### 2. Apply Coupon in Cart

```javascript
// POST /api/app/cart/calculate
const applyCoupon = async (couponCode) => {
  const response = await fetch('/api/app/cart/calculate', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      location_id: selectedLocationId,
      coupon_code: couponCode
    })
  });
  
  const data = await response.json();
  return data;
};
```

#### Handle Response
```javascript
const handleCouponResponse = (response) => {
  const { coupon_status, coupon_message, discount } = response.data;
  
  if (coupon_status === 200) {
    // Success
    showSuccess(coupon_message); // "Coupon applied successfully"
    updateCartTotals(response.data);
  } else {
    // Error (400)
    showError(coupon_message);
    // Possible error messages:
    // - "Invalid Coupon code"
    // - "Coupon is not valid or expired"
    // - "This coupon requires all cart items to be from {vendor_name}"
    // - "This coupon requires all cart items to be from {category_name} category"
    // - "This coupon requires all cart items to be from {brand_name} brand"
    // - "The minimum order total for this coupon is {min}"
  }
};
```

### 3. Display Cart with Coupon

```javascript
const CartSummary = ({ cartData }) => {
  return (
    <div className="cart-summary">
      <div className="line-item">
        <span>Subtotal:</span>
        <span>${cartData.sub_total}</span>
      </div>
      
      {cartData.discount > 0 && (
        <div className="line-item discount">
          <span>Discount:</span>
          <span>-${cartData.discount}</span>
        </div>
      )}
      
      <div className="line-item">
        <span>Shipping:</span>
        <span>${cartData.shipping_cost}</span>
      </div>
      
      <div className="line-item">
        <span>VAT:</span>
        <span>${cartData.vat}</span>
      </div>
      
      <div className="line-item total">
        <span>Total:</span>
        <span>${cartData.total}</span>
      </div>
      
      {cartData.coupon_message && (
        <div className={`coupon-message ${cartData.coupon_status === 200 ? 'success' : 'error'}`}>
          {cartData.coupon_message}
        </div>
      )}
    </div>
  );
};
```

### 4. Coupon Input Component

```javascript
const CouponInput = ({ onApply }) => {
  const [code, setCode] = useState('');
  const [loading, setLoading] = useState(false);
  
  const handleApply = async () => {
    if (!code.trim()) return;
    
    setLoading(true);
    try {
      const result = await applyCoupon(code);
      onApply(result);
    } catch (error) {
      showError('Failed to apply coupon');
    } finally {
      setLoading(false);
    }
  };
  
  return (
    <div className="coupon-input">
      <input
        type="text"
        placeholder="Enter coupon code"
        value={code}
        onChange={(e) => setCode(e.target.value.toUpperCase())}
      />
      <button onClick={handleApply} disabled={loading}>
        {loading ? 'Applying...' : 'Apply'}
      </button>
    </div>
  );
};
```

## Error Handling

### Common Error Messages

```javascript
const COUPON_ERRORS = {
  INVALID_CODE: 'Invalid Coupon code',
  EXPIRED: 'Coupon is not valid or expired',
  VENDOR_MISMATCH: 'This coupon requires all cart items to be from {vendor}',
  CATEGORY_MISMATCH: 'This coupon requires all cart items to be from {category} category',
  BRAND_MISMATCH: 'This coupon requires all cart items to be from {brand} brand',
  MIN_ORDER: 'The minimum order total for this coupon is {min}',
  MAX_ORDER: 'The maximum order total for this coupon is {max}',
  GUEST_USER: 'Guests cannot apply coupons'
};
```

### User-Friendly Messages

```javascript
const formatErrorMessage = (message) => {
  // Replace technical terms with user-friendly language
  return message
    .replace('cart items', 'products in your cart')
    .replace('order total', 'cart value');
};
```

## UI/UX Recommendations

### 1. Coupon Badge
Show coupon type on coupon cards:
```javascript
const getCouponBadge = (coupon) => {
  const badges = {
    general: { text: 'All Products', color: 'blue' },
    vendor: { text: 'Vendor Only', color: 'purple' },
    category: { text: 'Category Only', color: 'green' },
    brand: { text: 'Brand Only', color: 'orange' },
    first_order: { text: 'First Order', color: 'red' }
  };
  
  return badges[coupon.apply_on] || badges.general;
};
```

### 2. Cart Warning
When user has mixed cart and tries vendor/category/brand coupon:
```javascript
const CartWarning = ({ coupon, cartItems }) => {
  if (coupon.apply_on === 'vendor') {
    const hasMultipleVendors = new Set(cartItems.map(i => i.vendor_id)).size > 1;
    if (hasMultipleVendors) {
      return (
        <div className="warning">
          ⚠️ This coupon only works with products from {coupon.applicable_name}. 
          Remove items from other vendors to apply this coupon.
        </div>
      );
    }
  }
  return null;
};
```

### 3. First Order Indicator
```javascript
const FirstOrderBadge = () => (
  <div className="badge first-order">
    🎉 First Order Special
  </div>
);
```

## Testing Checklist

### Admin Panel
- [ ] Create general coupon
- [ ] Create vendor-specific coupon (vendor dropdown works)
- [ ] Create category-specific coupon (category dropdown works)
- [ ] Create brand-specific coupon (brand dropdown works)
- [ ] Create first-order coupon
- [ ] Edit existing coupon
- [ ] View coupon list with correct labels
- [ ] Filter/search coupons

### Mobile App
- [ ] View available coupons list
- [ ] Display coupon details correctly
- [ ] Apply general coupon to any cart
- [ ] Apply vendor coupon to vendor-only cart
- [ ] Try vendor coupon on mixed cart (should fail)
- [ ] Apply category coupon to category-only cart
- [ ] Try category coupon on mixed cart (should fail)
- [ ] Apply brand coupon to brand-only cart
- [ ] Try brand coupon on mixed cart (should fail)
- [ ] Apply first-order coupon as new user
- [ ] Try first-order coupon as existing user (should fail)
- [ ] View error messages correctly
- [ ] Remove coupon from cart
- [ ] Complete order with coupon

## API Endpoints Reference

### Admin
- `GET /api/dashboard/admin/coupons` - List coupons
- `POST /api/dashboard/admin/coupons` - Create coupon
- `GET /api/dashboard/admin/coupons/{id}` - Get coupon details
- `PUT /api/dashboard/admin/coupons/{id}` - Update coupon
- `DELETE /api/dashboard/admin/coupons/{id}` - Delete coupon

### App
- `GET /api/app/coupons` - List available coupons
- `POST /api/app/cart/calculate` - Apply coupon to cart
- `POST /api/app/orders` - Create order with coupon

## Support

For questions or issues, refer to:
- `COUPON_SYSTEM_DOCUMENTATION.md` - Complete system documentation
- `COUPON_IMPLEMENTATION_SUMMARY.md` - Technical implementation details
