<?php
/**
 * Cart Statistics Trait for ACR Tiles
 *
 * Provides shared cart statistics querying with caching to prevent
 * redundant database queries when multiple tiles need the same data.
 *
 * @package     EDD\Pro\CartRecovery\Admin\Reports\Endpoints\Tiles\Traits
 * @copyright   Copyright (c) 2026, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.6.5
 */

namespace EDD\Pro\CartRecovery\Admin\Reports\Endpoints\Tiles\Traits;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

/**
 * Trait for sharing cart statistics queries across multiple tiles.
 *
 * Uses a static cache to ensure the database query only runs once
 * even when multiple tiles request the same data.
 *
 * @since 3.6.5
 */
trait Carts {

	/**
	 * Cached cart statistics keyed by date range.
	 *
	 * @var array
	 */
	private static $cart_stats_cache = array();

	/**
	 * Gets cart statistics for the current date range.
	 *
	 * Results are cached statically so multiple tiles can access
	 * the same data without running redundant queries.
	 *
	 * @since 3.6.5
	 * @return array {
	 *     Cart statistics.
	 *
	 *     @type int   $total_carts     Total carts tracked.
	 *     @type int   $abandoned_count Carts with abandoned status.
	 *     @type int   $recovered_count Carts with recovered status.
	 *     @type float $total_value     Total cart value.
	 *     @type float $recovered_value Value of recovered carts.
	 *     @type float $recovery_rate   Recovery rate percentage.
	 * }
	 */
	protected function get_cart_stats(): array {
		global $wpdb;

		// Create cache key from date range.
		$cache_key = sprintf(
			'%s_%s',
			$this->dates['start']->format( 'Y-m-d-H-i-s' ),
			$this->dates['end']->format( 'Y-m-d-H-i-s' )
		);

		// Return cached result if available.
		if ( isset( self::$cart_stats_cache[ $cache_key ] ) ) {
			return self::$cart_stats_cache[ $cache_key ];
		}

		$table_name = $wpdb->prefix . 'edd_acr_carts';

		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safe.
		$stats = $wpdb->get_row(
			$wpdb->prepare(
				"SELECT
					COUNT(*) as total_carts,
					COUNT(CASE WHEN status = 'abandoned' THEN 1 END) as abandoned_count,
					COUNT(CASE WHEN status = 'recovered' THEN 1 END) as recovered_count,
					COALESCE(SUM(cart_total), 0) as total_value,
					COALESCE(SUM(CASE WHEN status = 'recovered' THEN cart_total ELSE 0 END), 0) as recovered_value
				FROM {$table_name}
				WHERE date_created BETWEEN %s AND %s",
				$this->dates['start']->format( 'Y-m-d H:i:s' ),
				$this->dates['end']->format( 'Y-m-d H:i:s' )
			)
		);

		if ( empty( $stats ) ) {
			$default_stats                        = $this->get_default_cart_stats();
			self::$cart_stats_cache[ $cache_key ] = $default_stats;

			return $default_stats;
		}

		$abandoned_count = (int) $stats->abandoned_count;
		$recovered_count = (int) $stats->recovered_count;

		// Calculate recovery rate: recovered / abandoned * 100.
		$recovery_rate = $abandoned_count > 0
			? round( ( $recovered_count / $abandoned_count ) * 100, 2 )
			: 0.0;

		$result = array(
			'total_carts'     => (int) $stats->total_carts,
			'abandoned_count' => $abandoned_count,
			'recovered_count' => $recovered_count,
			'total_value'     => (float) $stats->total_value,
			'recovered_value' => (float) $stats->recovered_value,
			'recovery_rate'   => $recovery_rate,
		);

		// Cache the result.
		self::$cart_stats_cache[ $cache_key ] = $result;

		return $result;
	}

	/**
	 * Returns default cart statistics structure.
	 *
	 * @since 3.6.5
	 * @return array
	 */
	private function get_default_cart_stats(): array {
		return array(
			'total_carts'     => 0,
			'abandoned_count' => 0,
			'recovered_count' => 0,
			'total_value'     => 0.0,
			'recovered_value' => 0.0,
			'recovery_rate'   => 0.0,
		);
	}
}
