# @ad-execute-manager/ad-reward

Reward ad-related classes including RewardAdFather and RewardAdNovel for ad management.

## Installation

```bash
npm install @ad-execute-manager/ad-reward
```

## Features

- **RewardAdFather**: Base class for reward ads with common functionality
- **RewardAdNovel**: Novel-specific reward ad implementation with enhanced features
- **AdExecuteManager**: Core ad execution management from @ad-execute-manager/core
- **TypeScript Support**: Includes TypeScript type definitions
- **Event Callbacks**: Comprehensive event callback system for ad lifecycle events
- **Error Handling**: Built-in error handling and retry mechanisms
- **Scene Support**: Scene-based ad configuration for different contexts
- **Reward Verification**: Support for reward verification and validation

## Usage

### RewardAdNovel

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

const rewardAd = RewardAdNovel.new({
  sign: 'novel_reward',
  preserveOnEnd: false,
  needEndOnTimeout: true,
  collection: {
    onHalfway: (args) => {
      console.log('Ad halfway:', args);
    },
    onShow: (args) => {
      console.log('Ad shown:', args);
    },
    onFinish: (args) => {
      console.log('Ad finished:', args);
    },
    onAlways: (args) => {
      console.log('Ad always:', args);
    },
    onError: (error) => {
      console.error('Ad error:', error);
    }
  }
});

// Initialize ad
rewardAd.initialize({
  adUnitId: 'your-ad-unit-id',
  retry: 3
});

// Show ad
const result = await rewardAd.addExecuteManager({
  options: {
    scene: 2,
    timeout: 10000
  }
});

console.log('Ad result:', result);
```

### Basic Reward Ad Usage

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

// Create reward ad instance
const rewardAd = RewardAdNovel.new({
  sign: 'premium_content_reward',
  preserveOnEnd: true,
  needEndOnTimeout: true,
  collection: {
    onFinish: (args) => {
      console.log('Reward ad finished, unlocking premium content');
      // Unlock premium content logic here
      unlockPremiumContent();
    },
    onError: (error) => {
      console.error('Reward ad error:', error);
      // Show error message to user
      showErrorMessage('Failed to load ad. Please try again later.');
    }
  }
});

// Initialize ad
rewardAd.initialize({ adUnitId: 'your-ad-unit-id', retry: 3 });

// Function to unlock premium content
function unlockPremiumContent() {
  // Logic to unlock premium content
  console.log('Premium content unlocked!');
}

// Function to show error message
function showErrorMessage(message) {
  // Logic to show error message
  console.log('Error:', message);
}

// Show reward ad to unlock premium content
async function showRewardAdForPremium() {
  try {
    const result = await rewardAd.addExecuteManager({ 
      options: { 
        scene: 2, 
        timeout: 15000 
      } 
    });
    console.log('Reward ad result:', result);
  } catch (error) {
    console.error('Reward ad execution error:', error);
  }
}

// Usage
// showRewardAdForPremium();
```

### Ad Instance Management

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

// Create ad instance
const rewardAd = RewardAdNovel.new({ sign: 'reward' });

// Initialize ad
rewardAd.initialize({ adUnitId: 'your-ad-unit-id', retry: 3 });

// Function to show ad based on user action
async function showAdBasedOnAction(action) {
  try {
    switch (action) {
      case 'unlock_premium':
        return await rewardAd.addExecuteManager({ 
          options: { 
            scene: 2, 
            timeout: 15000 
          } 
        });
      case 'get_coins':
        return await rewardAd.addExecuteManager({ 
          options: { 
            scene: 3, 
            timeout: 10000 
          } 
        });
      case 'continue_game':
        return await rewardAd.addExecuteManager({ 
          options: { 
            scene: 4, 
            timeout: 8000 
          } 
        });
      default:
        throw new Error('Invalid ad action');
    }
  } catch (error) {
    console.error('Ad error:', error);
    return { success: false, error: error.message };
  }
}

// Usage examples
// showAdBasedOnAction('unlock_premium');
// showAdBasedOnAction('get_coins');
// showAdBasedOnAction('continue_game');
```

## API

### RewardAdFather

Base class for reward ads with common functionality.

### RewardAdNovel

```typescript
class RewardAdNovel extends RewardAdFather {
  /**
   * Builds and returns an instance of RewardAdNovel
   * @param args Construction arguments
   * @returns Instance of RewardAdNovel
   */
  static build(args: IConstructArgs): RewardAdNovel;
  
  /**
   * Gets the singleton instance of RewardAdNovel
   * @returns Singleton instance of RewardAdNovel
   */
  static getInstance(): RewardAdNovel;
  
  /**
   * Creates a new instance of RewardAdNovel
   * @param args Construction arguments
   * @returns New instance of RewardAdNovel
   */
  static new(args: IConstructArgs): RewardAdNovel;
  
  /**
   * Initializes the ad with configuration
   * @param params Ad configuration parameters
   * @param callback Optional callback function
   * @returns Current instance for method chaining
   */
  initialize(params: IRewordAdConfig, callback?: (v: IRewardedVideoAd) => void): this;
  
  /**
   * Adds execute manager and runs the ad
   * @param ctx Context object with options
   * @returns Promise with ad execution result
   */
  addExecuteManager(ctx: any): Promise<any>;
  
  /**
   * Clears the ad instance
   */
  clear(): void;
  
  /**
   * Shifts the ad instance
   */
  shift(): void;
}
```

## Configuration

### Construction Arguments

When creating an ad instance, you can pass the following configuration options:

- **sign**: Unique identifier for the ad instance
- **preserveOnEnd**: Whether to preserve the instance after ad ends
- **needEndOnTimeout**: Whether to end the ad on timeout
- **collection**: Event collection object with callback functions
  - **onHalfway**: Called when ad reaches halfway point
  - **onShow**: Called when ad is shown
  - **onFinish**: Called when ad finishes
  - **onAlways**: Called always after ad operation
  - **onError**: Called when ad encounters error

### Initialize Parameters

When initializing an ad, you can pass the following parameters:

- **adUnitId**: Unique identifier for the ad unit
- **retry**: Number of retry attempts on ad error

## Examples

### Example 1: Premium Content Unlock

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

// Create reward ad instance for premium content
const premiumContentAd = RewardAdNovel.new({
  sign: 'premium_content_reward',
  preserveOnEnd: true,
  needEndOnTimeout: true,
  collection: {
    onShow: () => {
      console.log('Premium content reward ad shown');
      // Track reward ad show event
    },
    onFinish: (args) => {
      console.log('Premium content reward ad finished');
      // Unlock premium content
      unlockPremiumContent();
    },
    onError: (error) => {
      console.error('Premium content reward ad error:', error);
      // Show error message to user
      showError('Failed to load reward ad. Please try again later.');
    }
  }
});

// Initialize ad
premiumContentAd.initialize({ 
  adUnitId: 'your-ad-unit-id', 
  retry: 3 
});

// Function to unlock premium content
function unlockPremiumContent() {
  console.log('Unlocking premium content...');
  // Premium content unlock logic here
  // For example: unlock chapters, remove ads, give bonus content
}

// Function to show error message
function showError(message) {
  console.error('Error:', message);
  // Error message display logic here
}

// Show reward ad to unlock premium content
async function unlockPremiumWithAd() {
  console.log('Showing reward ad to unlock premium content...');
  try {
    await premiumContentAd.addExecuteManager({ 
      options: { 
        scene: 2, // Premium content unlock scene
        timeout: 15000 
      } 
    });
  } catch (error) {
    console.error('Error showing premium content reward ad:', error);
    showError('Failed to load reward ad. Please try again later.');
  }
}
```

### Example 2: In-Game Currency Reward

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

// Create reward ad instance for in-game currency
const currencyAd = RewardAdNovel.new({
  sign: 'game_currency_reward',
  preserveOnEnd: true,
  needEndOnTimeout: true,
  collection: {
    onShow: () => {
      console.log('In-game currency reward ad shown');
      // Track currency reward ad show event
    },
    onFinish: (args) => {
      console.log('In-game currency reward ad finished');
      // Give player in-game currency
      giveCurrency(100); // Give 100 coins
    },
    onError: (error) => {
      console.error('In-game currency reward ad error:', error);
      // Show error message to player
      showGameError('Failed to load reward ad. Please try again later.');
    }
  }
});

// Initialize ad
currencyAd.initialize({ 
  adUnitId: 'your-ad-unit-id', 
  retry: 2 
});

// Function to give in-game currency
function giveCurrency(amount) {
  console.log(`Giving ${amount} coins to player...`);
  // In-game currency award logic here
  // For example: update player balance, show reward animation
}

// Function to show game error message
function showGameError(message) {
  console.error('Game error:', message);
  // Game error message display logic here
}

// Show reward ad to get in-game currency
async function getCurrencyWithAd() {
  console.log('Showing reward ad to get in-game currency...');
  try {
    await currencyAd.addExecuteManager({ 
      options: { 
        scene: 3, // In-game currency reward scene
        timeout: 10000 
      } 
    });
  } catch (error) {
    console.error('Error showing currency reward ad:', error);
    showGameError('Failed to load reward ad. Please try again later.');
  }
}
```

### Example 3: Continue Game After Defeat

```javascript
import { RewardAdNovel } from '@ad-execute-manager/ad-reward';

// Create reward ad instance for continue game
const continueGameAd = RewardAdNovel.new({
  sign: 'continue_game_reward',
  preserveOnEnd: false,
  needEndOnTimeout: true,
  collection: {
    onShow: () => {
      console.log('Continue game reward ad shown');
      // Track continue game reward ad show event
    },
    onFinish: (args) => {
      console.log('Continue game reward ad finished');
      // Continue game from where player left off
      continueGame();
    },
    onError: (error) => {
      console.error('Continue game reward ad error:', error);
      // Show error message and go to game over
      showGameOver();
    }
  }
});

// Initialize ad
continueGameAd.initialize({ 
  adUnitId: 'your-ad-unit-id', 
  retry: 1 
});

// Function to continue game
function continueGame() {
  console.log('Continuing game...');
  // Game continuation logic here
  // For example: restore player position, health, game state
}

// Function to show game over
function showGameOver() {
  console.log('Showing game over screen...');
  // Game over screen logic here
}

// Show reward ad to continue game
async function continueGameWithAd() {
  console.log('Showing reward ad to continue game...');
  try {
    await continueGameAd.addExecuteManager({ 
      options: { 
        scene: 4, // Continue game scene
        timeout: 8000 
      } 
    });
  } catch (error) {
    console.error('Error showing continue game reward ad:', error);
    showGameOver();
  }
}
```

## Dependencies

- **@ad-execute-manager/core**: Core ad execution management
- **@ad-execute-manager/logger**: Logging utility
- **@ad-execute-manager/serializable-error**: Serializable error implementation

## License

MIT
