# Coupon Validation Helper Usage Guide

This document explains how to use the `couponValidationHelper.js` utility functions across different modules in the application.

## Overview

The coupon validation helper provides comprehensive validation for coupon codes with minimum points checking, contractor eligibility verification, and discount calculations.

## Available Functions

### 1. `validateCouponWithPoints(couponCode, userId)`

The main validation function that checks:
- Coupon code validity
- Referral system status
- Contractor existence
- Minimum points requirement
- Coupon campaign status
- Usage limits

**Parameters:**
- `couponCode` (string): The coupon code to validate
- `userId` (string): The contractor's user ID

**Returns:**
```javascript
{
  valid: boolean,
  couponCode: string,
  stripeCouponId: string,
  discount: number,
  discountType: 'percentage' | 'fixed',
  discountPercentage: number | null,
  discountAmount: number | null,
  currency: string,
  minimumPoints: number,
  contractorPoints: number,
  error: string | null,
  reason: string
}
```

### 2. `calculateDiscountAmount(couponValidation, basePrice)`

Calculates the final discount amount based on coupon type and base price.

**Parameters:**
- `couponValidation` (object): Result from `validateCouponWithPoints`
- `basePrice` (number): Base price in cents

**Returns:** Final discount amount in cents

### 3. `checkContractorPoints(userId, requiredPoints)`

Checks if a contractor has sufficient points.

**Parameters:**
- `userId` (string): Contractor ID
- `requiredPoints` (number): Minimum points required

**Returns:**
```javascript
{
  hasSufficientPoints: boolean,
  currentPoints: number,
  requiredPoints: number,
  deficit: number
}
```

### 4. `getContractorPointsSummary(userId)`

Gets a summary of contractor points and referral statistics.

**Parameters:**
- `userId` (string): Contractor ID

**Returns:**
```javascript
{
  contractorId: string,
  contractorName: string,
  totalPoints: number,
  successfulReferrals: number,
  joinedUsers: number,
  lastUpdated: Date
}
```

## Usage Examples

### Example 1: Basic Coupon Validation

```javascript
import { validateCouponWithPoints, calculateDiscountAmount } from '../utils/couponValidationHelper.js';

// In your controller
export const validateCoupon = async (req, res) => {
  const { couponCode } = req.body;
  const { userId } = req.user;

  const validation = await validateCouponWithPoints(couponCode, userId);

  if (!validation.valid) {
    return res.status(400).json({
      success: false,
      message: validation.error,
      reason: validation.reason
    });
  }

  // Calculate discount for a £200 service
  const basePrice = 20000; // £200 in cents
  const discountAmount = calculateDiscountAmount(validation, basePrice);
  const finalPrice = basePrice - discountAmount;

  return res.json({
    success: true,
    coupon: {
      code: validation.couponCode,
      discountType: validation.discountType,
      discountAmount: discountAmount,
      finalPrice: finalPrice
    },
    points: {
      required: validation.minimumPoints,
      current: validation.contractorPoints
    }
  });
};
```

### Example 2: Points Check Before Service Purchase

```javascript
import { checkContractorPoints } from '../utils/couponValidationHelper.js';

export const checkEligibility = async (req, res) => {
  const { userId } = req.user;
  const { serviceType } = req.body;

  // Define minimum points for different services
  const serviceRequirements = {
    'premium': 50,
    'standard': 20,
    'basic': 0
  };

  const requiredPoints = serviceRequirements[serviceType] || 0;
  const pointsCheck = await checkContractorPoints(userId, requiredPoints);

  return res.json({
    eligible: pointsCheck.hasSufficientPoints,
    currentPoints: pointsCheck.currentPoints,
    requiredPoints: pointsCheck.requiredPoints,
    deficit: pointsCheck.deficit
  });
};
```

### Example 3: Points Summary for Dashboard

```javascript
import { getContractorPointsSummary } from '../utils/couponValidationHelper.js';

export const getPointsDashboard = async (req, res) => {
  const { userId } = req.user;

  const summary = await getContractorPointsSummary(userId);

  return res.json({
    success: true,
    data: summary
  });
};
```

## Error Handling

The helper functions return detailed error information:

```javascript
// Example error responses
{
  valid: false,
  error: "Insufficient points. Required: 50, Available: 30",
  reason: "INSUFFICIENT_POINTS",
  requiredPoints: 50,
  currentPoints: 30
}

{
  valid: false,
  error: "Referral system is currently disabled",
  reason: "SYSTEM_DISABLED"
}

{
  valid: false,
  error: "You have already used this coupon code",
  reason: "ALREADY_USED"
}
```

## Integration with Existing Code

To integrate with existing coupon validation:

1. **Replace existing validation calls:**
```javascript
// Old way
const referral = await ReferralModel.findValidDiscountByCode(couponCode);

// New way
const validation = await validateCouponWithPoints(couponCode, userId);
```

2. **Update discount calculations:**
```javascript
// Old way
const discount = referral.discount;

// New way
const discountAmount = calculateDiscountAmount(validation, basePrice);
```

3. **Enhanced error responses:**
```javascript
// Include points information in error responses
if (!validation.valid) {
  return res.status(400).json({
    message: validation.error,
    reason: validation.reason,
    ...(validation.requiredPoints && { 
      requiredPoints: validation.requiredPoints,
      currentPoints: validation.currentPoints 
    })
  });
}
```

## Best Practices

1. **Always check validation.valid** before using discount information
2. **Use calculateDiscountAmount()** for consistent discount calculations
3. **Include points information** in API responses for better UX
4. **Handle all error cases** with appropriate user messages
5. **Log validation errors** for debugging and monitoring

## Testing

Test the helper functions with various scenarios:

```javascript
// Test cases to consider:
- Valid coupon with sufficient points
- Valid coupon with insufficient points
- Invalid coupon code
- Disabled referral system
- Expired coupon
- Already used coupon
- Different discount types (percentage vs fixed)
```
