<?php
/**
 * Transient-based cache implementation.
 *
 * @package PDFDraft
 */

namespace PDFDraft\Support\Cache;

use PDFDraft\Contracts\Cache\CacheInterface;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Cache implementation using WordPress transients.
 */
class TransientCache implements CacheInterface {

	/**
	 * Cache key prefix.
	 *
	 * @var string
	 */
	private string $prefix;

	/**
	 * Constructor.
	 *
	 * @param string $prefix Cache key prefix.
	 */
	public function __construct( string $prefix = 'pdfdraft_' ) {
		$this->prefix = $prefix;
	}

	/**
	 * Get a cached value by key.
	 *
	 * @param string $key          Cache key.
	 * @param mixed  $defaultValue Default value if not found.
	 * @return mixed Cached value or default.
	 */
	public function get( string $key, $defaultValue = null ) {
		$value = get_transient( $this->prefix . $key );

		return false === $value ? $defaultValue : $value;
	}

	/**
	 * Set a cached value.
	 *
	 * @param string $key   Cache key.
	 * @param mixed  $value Value to cache.
	 * @param int    $ttl   Time to live in seconds.
	 * @return bool Whether the value was set.
	 */
	public function set( string $key, $value, int $ttl = 3600 ): bool {
		return set_transient( $this->prefix . $key, $value, $ttl );
	}

	/**
	 * Delete a cached value.
	 *
	 * @param string $key Cache key.
	 * @return bool Whether the value was deleted.
	 */
	public function delete( string $key ): bool {
		return delete_transient( $this->prefix . $key );
	}

	/**
	 * Check if a key exists in cache.
	 *
	 * @param string $key Cache key.
	 * @return bool Whether the key exists.
	 */
	public function has( string $key ): bool {
		return false !== get_transient( $this->prefix . $key );
	}

	/**
	 * Clear all cached values with the configured prefix.
	 *
	 * @return bool Whether the cache was cleared.
	 */
	public function clear(): bool {
		global $wpdb;
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		$result = $wpdb->query(
			$wpdb->prepare(
				"DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
				'_transient_' . $this->prefix . '%',
				'_transient_timeout_' . $this->prefix . '%'
			)
		);
		return false !== $result;
	}
}
