<?php
/**
 * Cache Manager
 *
 * Implements caching for expensive operations.
 *
 * @package DonorCore\Performance
 */

namespace DonorCore\Performance;

defined( 'ABSPATH' ) || exit;

/**
 * Cache Manager Class
 */
class Cache_Manager {

	/**
	 * Cache duration in seconds (30 minutes).
	 */
	const CACHE_DURATION = 1800;

	/**
	 * Initialize hooks.
	 */
	public function init() {
		add_action( 'woocommerce_payment_complete', array( $this, 'invalidate_campaign_cache' ), 100, 1 );
		add_action( 'save_post_donorcore_campaign', array( $this, 'invalidate_campaign_cache_on_save' ), 10, 1 );
	}

	/**
	 * Get cached campaign total.
	 *
	 * @param int $campaign_id Campaign ID.
	 * @return float|null
	 */
	public function get_campaign_total( $campaign_id ) {
		$cache_key = 'donorcore_campaign_total_' . $campaign_id;
		$total     = get_transient( $cache_key );

		if ( false !== $total ) {
			return floatval( $total );
		}

		// Calculate and cache.
		$donation_repo = new \DonorCore\Database\Donation_Log_Repository();
		$total         = $donation_repo->get_campaign_total( $campaign_id );

		set_transient( $cache_key, $total, self::CACHE_DURATION );

		return floatval( $total );
	}

	/**
	 * Invalidate campaign cache on donation.
	 *
	 * @param int $order_id Order ID.
	 */
	public function invalidate_campaign_cache( $order_id ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return;
		}

		foreach ( $order->get_items() as $item ) {
			$campaign_id = $item->get_meta( '_donorcore_campaign_id', true );

			if ( $campaign_id ) {
				$this->delete_campaign_cache( $campaign_id );
			}
		}
	}

	/**
	 * Invalidate campaign cache on save.
	 *
	 * @param int $post_id Post ID.
	 */
	public function invalidate_campaign_cache_on_save( $post_id ) {
		$this->delete_campaign_cache( $post_id );
	}

	/**
	 * Delete campaign cache.
	 *
	 * @param int $campaign_id Campaign ID.
	 */
	private function delete_campaign_cache( $campaign_id ) {
		delete_transient( 'donorcore_campaign_total_' . $campaign_id );
		delete_transient( 'donorcore_campaign_stats_' . $campaign_id );
	}

	/**
	 * Get cached top donors.
	 *
	 * @param int $limit Limit.
	 * @return array
	 */
	public function get_top_donors( $limit = 10 ) {
		$cache_key = 'donorcore_top_donors_' . $limit;
		$donors    = get_transient( $cache_key );

		if ( false !== $donors ) {
			return $donors;
		}

		// Calculate and cache.
		$analytics_repo = new \DonorCore\Database\Donor_Analytics_Repository();
		$donors         = $analytics_repo->get_top_donors( $limit );

		set_transient( $cache_key, $donors, self::CACHE_DURATION );

		return $donors;
	}

	/**
	 * Invalidate all caches.
	 */
	public function invalidate_all() {
		global $wpdb;

		// Delete all DonorCore transients.
		// Using $wpdb->options (core table) with LIKE pattern for prefix-based cleanup
		// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk transient invalidation by prefix
		$wpdb->query(
			"DELETE FROM `{$wpdb->options}` 
			WHERE option_name LIKE '_transient_donorcore_%' 
			OR option_name LIKE '_transient_timeout_donorcore_%'"
		);
	}
}
