<?php
/**
 * Objects: Payout_Batch
 *
 * Represents a single batch of payouts created in one run (e.g. a Pay Affiliates
 * submission that generated N per-affiliate payouts). Gives operators a unit of
 * reconciliation, retry, and reporting that groups related payouts together.
 *
 * @package     AffiliateWP
 * @subpackage  Database
 * @copyright   Copyright (c) 2026, Sandhills Development, LLC
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       2.33.0
 */

namespace AffWP\Affiliate;

#[\AllowDynamicProperties]

/**
 * Implements a payout batch object.
 *
 * @since 2.33.0
 *
 * @see AffWP\Base_Object
 * @see affwp_get_payout_batch()
 *
 * @property-read int $ID Alias for `$batch_id`.
 */
final class Payout_Batch extends \AffWP\Base_Object {

	/**
	 * Batch ID.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $batch_id = 0;

	/**
	 * Date the batch was created.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $date_created;

	/**
	 * User ID of the admin who started the batch.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $created_by = 0;

	/**
	 * Payout method for the batch, or 'mixed' when affiliates in the batch use different methods.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $payout_method = '';

	/**
	 * Batch status. One of: processing, completed, partial, failed, canceled.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $status = 'processing';

	/**
	 * Sum of the amounts of all payouts in the batch.
	 *
	 * @since 2.33.0
	 * @var   float
	 */
	public $total_amount = 0;

	/**
	 * Total number of payouts in the batch.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $total_count = 0;

	/**
	 * Number of payouts that have reached a terminal success state.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $processed_count = 0;

	/**
	 * Number of payouts that have reached a terminal failure state.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $failed_count = 0;

	/**
	 * Our idempotency key sent to the processor (e.g. PayPal's sender_batch_id).
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $sender_batch_id = '';

	/**
	 * The processor's returned batch identifier (e.g. PayPal's payout_batch_id).
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $provider_batch_id = '';

	/**
	 * Parent batch ID when this batch is a retry of a previous batch. Zero for originals.
	 *
	 * @since 2.33.0
	 * @var   int
	 */
	public $retry_of_batch_id = 0;

	/**
	 * JSON-encoded list of processor errors associated with this batch.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $processing_errors = '';

	/**
	 * JSON-encoded blob of arbitrary method-specific context (filters used, webhook state, etc.).
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public $meta = '';

	/**
	 * Token for building cache keys.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public static $cache_token = 'affwp_payout_batches';

	/**
	 * Database group used by \AffWP\Base_Object to reach the DB class.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public static $db_group = 'affiliates:payout_batches';

	/**
	 * Object type — used as the cache group and for accessing object DB classes in the parent.
	 *
	 * @since 2.33.0
	 * @var   string
	 */
	public static $object_type = 'payout_batches';

	/**
	 * Sanitizes a payout batch object field.
	 *
	 * @since 2.33.0
	 *
	 * @param string $field Object field.
	 * @param mixed  $value Field value.
	 * @return mixed Sanitized field value.
	 */
	public static function sanitize_field( $field, $value ) {
		$ints = array(
			'batch_id',
			'ID',
			'created_by',
			'total_count',
			'processed_count',
			'failed_count',
			'retry_of_batch_id',
		);

		if ( in_array( $field, $ints, true ) ) {
			$value = (int) $value;
		}

		if ( 'total_amount' === $field ) {
			$value = floatval( $value );
		}

		return $value;
	}
}
