# Coupon System Implementation Guide

## Overview
The coupon system allows users to apply discount codes for various services. Each coupon can only be used **once per account** to ensure fair usage.

## Features
- ✅ Multiple discount types (percentage off, free/100% off)
- ✅ Service-specific coupons (website submission, directory, job post, AI website)
- ✅ One-time use per user account
- ✅ Global usage limits
- ✅ Expiration date validation
- ✅ User tracking of used coupons

## Available Coupons

### 1. NOCOST - First Website Submission
- **Discount**: 100% OFF (Free)
- **Original Price**: $12.99 USD
- **Valid For**: Website Submission, AI Website Submission
- **Valid Until**: January 30, 2026
- **Code**: `NOCOST`

### 2. FWF01 - Second Website Submission
- **Discount**: 70% OFF
- **Original Price**: $12.99 USD (You pay $3.90)
- **Valid For**: Website Submission, AI Website Submission
- **Valid Until**: January 30, 2026
- **Code**: `FWF01`

### 3. NOCOST_JOB - First Job Vacancy Post
- **Discount**: 100% OFF (Free)
- **Original Price**: $15.99 USD
- **Valid For**: Job Post
- **Valid Until**: January 30, 2026
- **Code**: `NOCOST_JOB`

### 4. NOCOST_DIR - Directory Submission
- **Discount**: 100% OFF (Free)
- **Original Price**: $6.99 USD
- **Valid For**: Directory Submission
- **Valid Until**: January 30, 2026
- **Code**: `NOCOST_DIR`

## API Endpoints

### 1. Validate Coupon (Check Before Payment)
**Endpoint**: `POST /api/coupon/validate`

**Authentication**: Required (Bearer Token)

**Request Body**:
```json
{
  "couponCode": "NOCOST",
  "serviceType": "websiteSubmission"
}
```

**Service Types**:
- `websiteSubmission` - Website submission
- `directory` - Directory submission
- `jobPost` - Job post
- `aiWebsite` - AI website submission

**Response (Valid)**:
```json
{
  "isValid": true,
  "discount": 100,
  "discountType": "free",
  "serviceType": ["websiteSubmission", "aiWebsite"],
  "message": "Coupon applied successfully - 100% discount!"
}
```

**Response (Invalid - Already Used)**:
```json
{
  "isValid": false,
  "message": "You have already used this coupon. Each coupon can only be used once per account."
}
```

**Response (Invalid - Wrong Service)**:
```json
{
  "isValid": false,
  "message": "This coupon is not valid for jobPost. Valid for: websiteSubmission, aiWebsite"
}
```

### 2. Apply Coupon (After Payment Verification)
**Endpoint**: `POST /api/coupon/apply`

**Authentication**: Required (Bearer Token)

**Request Body**:
```json
{
  "couponCode": "NOCOST",
  "serviceType": "websiteSubmission"
}
```

**Response (Success)**:
```json
{
  "success": true,
  "discount": 100,
  "discountType": "free",
  "message": "Coupon applied successfully",
  "coupon": {
    "code": "NOCOST",
    "discountAmount": 100,
    "discountType": "free"
  }
}
```

**Response (Error)**:
```json
{
  "success": false,
  "message": "You have already used this coupon"
}
```

### 3. Get User's Used Coupons
**Endpoint**: `GET /api/coupon/my-coupons`

**Authentication**: Required (Bearer Token)

**Response**:
```json
{
  "success": true,
  "usedCoupons": [
    {
      "couponId": "65f7a1b2c3d4e5f6a7b8c9d0",
      "code": "NOCOST",
      "usedAt": "2024-12-08T10:30:00.000Z",
      "serviceType": "websiteSubmission",
      "discountAmount": 100
    }
  ]
}
```

### 4. Create Coupon (Admin)
**Endpoint**: `POST /api/coupon/create`

**Request Body**:
```json
{
  "code": "SUMMER2024",
  "discountType": "percentage",
  "discountAmount": 50,
  "serviceType": ["websiteSubmission", "directory"],
  "validFrom": "2024-06-01",
  "validUntil": "2024-08-31",
  "maxUsage": 100,
  "isActive": true
}
```

## Frontend Integration

### Step 1: Validate Coupon Before Payment
```javascript
const validateCoupon = async (couponCode, serviceType) => {
  try {
    const response = await fetch('/api/coupon/validate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({ couponCode, serviceType })
    });
    
    const data = await response.json();
    
    if (data.isValid) {
      // Show discount to user
      const originalPrice = 12.99; // Example
      const discount = data.discountType === 'free' 
        ? originalPrice 
        : (originalPrice * data.discount / 100);
      const finalPrice = originalPrice - discount;
      
      console.log(`Discount: $${discount.toFixed(2)}`);
      console.log(`Final Price: $${finalPrice.toFixed(2)}`);
      
      return { valid: true, discount: data.discount, discountType: data.discountType };
    } else {
      // Show error message
      alert(data.message);
      return { valid: false };
    }
  } catch (error) {
    console.error('Error validating coupon:', error);
    return { valid: false };
  }
};
```

### Step 2: Apply Coupon After Payment
```javascript
const applyCoupon = async (couponCode, serviceType) => {
  try {
    const response = await fetch('/api/coupon/apply', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${token}`
      },
      body: JSON.stringify({ couponCode, serviceType })
    });
    
    const data = await response.json();
    
    if (data.success) {
      console.log('Coupon applied successfully!');
      return true;
    } else {
      console.error('Failed to apply coupon:', data.message);
      return false;
    }
  } catch (error) {
    console.error('Error applying coupon:', error);
    return false;
  }
};
```

### Step 3: Complete Workflow Example
```javascript
// User enters coupon code
const handleSubmitWithCoupon = async () => {
  const couponCode = 'NOCOST';
  const serviceType = 'websiteSubmission';
  const originalPrice = 12.99;
  
  // 1. Validate coupon
  const validation = await validateCoupon(couponCode, serviceType);
  
  if (!validation.valid) {
    return; // Stop if invalid
  }
  
  // 2. Calculate final price
  const discount = validation.discountType === 'free' 
    ? originalPrice 
    : (originalPrice * validation.discount / 100);
  const finalPrice = originalPrice - discount;
  
  // 3. Process payment (if finalPrice > 0)
  if (finalPrice > 0) {
    const paymentOrderID = await processPayPalPayment(finalPrice);
    
    // 4. Apply coupon after payment
    await applyCoupon(couponCode, serviceType);
    
    // 5. Submit form with paymentOrderID
    await submitWebsite({ ...formData, paymentOrderID });
  } else {
    // Free submission
    // 4. Apply coupon
    await applyCoupon(couponCode, serviceType);
    
    // 5. Submit form without payment
    await submitWebsite({ ...formData, paymentOrderID: 'FREE_WITH_COUPON' });
  }
};
```

## Database Schema

### Coupon Model
```javascript
{
  code: String, // Unique coupon code
  discountType: String, // 'percentage' or 'free'
  discountAmount: Number, // Percentage (70) or 100 for free
  serviceType: [String], // Array of service types
  validFrom: Date,
  validUntil: Date,
  maxUsage: Number, // Global usage limit
  usageCount: Number, // Current usage count
  isActive: Boolean,
  usedBy: [ObjectId] // Array of user IDs who used this coupon
}
```

### User Model (Added Field)
```javascript
{
  // ...existing fields
  usedCoupons: [{
    couponId: ObjectId,
    code: String,
    usedAt: Date,
    serviceType: String,
    discountAmount: Number
  }]
}
```

## Setup Instructions

### 1. Run the Coupon Creation Script
```bash
cd Backend/Backend
node create-coupons.js
```

This will create all the coupons defined in the image with proper validation dates.

### 2. Verify Coupons Created
Check your MongoDB database to ensure coupons were created:
```bash
# Using MongoDB shell
use your_database_name
db.coupons.find().pretty()
```

## Testing

### Test Case 1: Valid Coupon First Use
```bash
# User validates coupon (first time)
curl -X POST http://localhost:5000/api/coupon/validate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "couponCode": "NOCOST",
    "serviceType": "websiteSubmission"
  }'

# Expected: isValid: true, discount: 100
```

### Test Case 2: Coupon Already Used
```bash
# Same user tries to use same coupon again
curl -X POST http://localhost:5000/api/coupon/validate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "couponCode": "NOCOST",
    "serviceType": "websiteSubmission"
  }'

# Expected: isValid: false, message: "You have already used this coupon..."
```

### Test Case 3: Wrong Service Type
```bash
# User tries to use website coupon for job post
curl -X POST http://localhost:5000/api/coupon/validate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "couponCode": "NOCOST",
    "serviceType": "jobPost"
  }'

# Expected: isValid: false, message: "This coupon is not valid for jobPost..."
```

## Important Notes

1. **One-Time Use**: Each coupon can only be used once per user account
2. **Service-Specific**: Coupons are tied to specific service types
3. **Validation Required**: Always validate coupons before showing discounted prices
4. **Apply After Payment**: Only apply the coupon after payment verification (or for free submissions)
5. **Track Usage**: The system tracks usage in both the Coupon and User models

## Troubleshooting

### Issue: User can't use coupon
- Check if coupon is still active (`isActive: true`)
- Check if coupon hasn't expired (`validUntil`)
- Check if user hasn't already used it (`usedCoupons` array)
- Check if coupon applies to the service type

### Issue: Coupon not found
- Verify coupon code is correct (case-sensitive)
- Check if coupon exists in database
- Ensure coupon is active

### Issue: Payment still required for free coupon
- Ensure `discountType` is set to `'free'`
- Ensure `discountAmount` is 100
- Calculate final price properly in frontend

## Security Considerations

1. Always verify coupon on backend before accepting payment
2. Use authentication middleware to prevent unauthorized access
3. Track coupon usage to prevent abuse
4. Validate service type matches coupon restrictions
5. Double-check payment status before applying coupon

## Future Enhancements

- Admin dashboard to manage coupons
- Bulk coupon generation
- User-specific coupons (email-based)
- Coupon analytics and reporting
- Automated expiration notifications
- Referral coupon system
