<?php
/**
 * AbstractNotification.php.
 *
 * @package RewardsWP
 */

namespace Awesomemotive\Rewardswp\Abstracts;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Awesomemotive\Rewardswp\Interfaces\NotificationInterface;
use function Awesomemotive\Rewardswp\Helpers\extract_placeholders;
use function Awesomemotive\Rewardswp\Helpers\get_placeholders_with_labels;

/**
 * Base abstract notification with placeholder helpers.
 */
abstract class AbstractNotification implements NotificationInterface {
	/**
	 * The data to replace placeholders.
	 *
	 * @var array
	 */
	protected array $data = [];

	/**
	 * Set the data used to replace placeholders in the content.
	 *
	 * This method accepts a 2D associative array where the keys represent the
	 * placeholders (e.g., {name}, {email}) and the values are the corresponding
	 * data that will replace these placeholders in the content.
	 *
	 * For example, passing an array like:
	 * [
	 *    'name' => 'John Doe',
	 *    'email' => 'johndoe@example.com'
	 * ]
	 * will replace {name} with 'John Doe' and {email} with 'johndoe@example.com'
	 * in the notification content.
	 *
	 * @param array $data A 2D associative array with key-value pairs for placeholder replacements.
	 *
	 * @return self Returns the instance of the current class.
	 */
	public function set_data( array $data ): self {
		$this->data = $data;
		return $this;
	}

	/**
	 * Retrieve the array of data to replace the content placeholders.
	 *
	 * @since 1.0.0
	 *
	 * @return array Data to replace placeholders.
	 */
	public function get_data(): array {
		return $this->data;
	}

	/**
	 * Retrieve the notification content.
	 *
	 * @return string
	 */
	abstract public function get_content(): string;

	/**
	 * A method to send a notification.
	 *
	 * @return bool
	 */
	abstract public function send(): bool;

	/**
	 * Get available placeholders from the notification content.
	 *
	 * Extracts all placeholders from the content and returns them as an array.
	 * This method is useful for dynamically discovering what placeholders are available
	 * in a notification without hardcoding them.
	 *
	 * @since 1.0.0
	 *
	 * @return array Array of unique placeholder names (without the braces).
	 */
	public function get_available_placeholders(): array {
		return extract_placeholders( $this->get_content() );
	}

	/**
	 * Get available placeholders with display labels.
	 *
	 * Returns placeholders from the content with formatted labels for UI display.
	 * Converts snake_case placeholders to Title Case labels.
	 *
	 * @since 1.0.0
	 *
	 * @return array Associative array with placeholder => label pairs.
	 */
	public function get_placeholders_with_labels(): array {
		return get_placeholders_with_labels( $this->get_content() );
	}
}
