<?php
/**
 * Shared TutorHelper email template registry.
 *
 * @package TutorHelper_Bookings
 */

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

/**
 * Registers and retrieves TutorHelper email templates.
 *
 * Individual modules and add-ons register their own templates here.
 * Core users may enable or disable registered templates and edit their
 * subject/body text. Creating arbitrary templates is reserved for Pro.
 */
final class TutorHelper_Email_Templates {

	/**
	 * Option storing email template overrides.
	 *
	 * @var string
	 */
	const OPTION_NAME =
		'tutorhelper_email_templates';

	/**
	 * Registered template definitions.
	 *
	 * @var array
	 */
	private static $templates = array();

	/**
	 * Register one email template.
	 *
	 * @param string $template_key Template identifier.
	 * @param array  $definition   Template definition.
	 *
	 * @return bool
	 */
	public static function register(
		$template_key,
		$definition
	) {
		$template_key =
			sanitize_key(
				$template_key
			);

		if (
			'' === $template_key
			|| ! is_array( $definition )
		) {
			return false;
		}

		$defaults = array(
			'key' =>
				$template_key,

			'module' =>
				'',

			'label' =>
				$template_key,

			'description' =>
				'',
			
			'heading' =>
				$template_key,

			'recipient' =>
				'',

			'enabled' =>
				true,

			'subject' =>
				'',

			'body' =>
				'',

			'placeholders' =>
				array(),
			
			
		);

		$template =
			wp_parse_args(
				$definition,
				$defaults
			);

		$template['key'] =
			$template_key;

		$template['module'] =
			sanitize_key(
				$template['module']
			);

		$template['label'] =
			sanitize_text_field(
				$template['label']
			);

		$template['description'] =
			sanitize_text_field(
				$template['description']
			);

		$template['heading'] =
			sanitize_text_field(
				$template['heading']
			);

		$template['recipient'] =
			sanitize_key(
				$template['recipient']
			);

		$template['enabled'] =
			(bool) $template['enabled'];

		$template['subject'] =
			sanitize_text_field(
				$template['subject']
			);

		$template['body'] =
			wp_kses_post(
				$template['body']
			);

		$template['placeholders'] =
			self::sanitize_placeholders(
				$template['placeholders']
			);

		self::$templates[
			$template_key
		] =
			$template;

		return true;
	}

	/**
	 * Return all registered templates with tutor overrides applied.
	 *
	 * @return array
	 */
	public static function get_all() {
		$saved =
			self::get_saved_overrides();

		$templates = array();

		foreach (
			self::$templates
			as $template_key => $definition
		) {
			$override =
				isset(
					$saved[ $template_key ]
				)
				&& is_array(
					$saved[ $template_key ]
				)
					? $saved[ $template_key ]
					: array();

			$templates[ $template_key ] =
				self::merge_template(
					$definition,
					$override
				);
		}

		return $templates;
	}

	/**
	 * Return all registered templates belonging to one module.
	 *
	 * @param string $module Module key.
	 *
	 * @return array
	 */
	public static function get_by_module(
		$module
	) {
		$module =
			sanitize_key(
				$module
			);

		$templates =
			self::get_all();

		return array_filter(
			$templates,
			static function ( $template ) use ( $module ) {
				return isset(
					$template['module']
				)
				&& $module
				=== $template['module'];
			}
		);
	}

	/**
	 * Return one registered template.
	 *
	 * @param string $template_key Template identifier.
	 *
	 * @return array|null
	 */
	public static function get(
		$template_key
	) {
		$template_key =
			sanitize_key(
				$template_key
			);

		$templates =
			self::get_all();

		return isset(
			$templates[ $template_key ]
		)
			? $templates[ $template_key ]
			: null;
	}

	/**
	 * Determine whether a registered template is enabled.
	 *
	 * @param string $template_key Template identifier.
	 *
	 * @return bool
	 */
	public static function is_enabled(
		$template_key
	) {
		$template =
			self::get(
				$template_key
			);

		return $template
			&& ! empty(
				$template['enabled']
			);
	}

	/**
	 * Save Core-editable settings for one template.
	 *
	 * Core permits only:
	 * - enabled
	 * - subject
	 * - body
	 *
	 * Template creation, triggers, recipient rules and layouts remain
	 * controlled by the registering module or Pro.
	 *
	 * @param string $template_key Template identifier.
	 * @param array  $data         Submitted settings.
	 *
	 * @return true|WP_Error
	 */
	public static function save(
		$template_key,
		$data
	) {
		$template_key =
			sanitize_key(
				$template_key
			);

		if (
			! isset(
				self::$templates[
					$template_key
				]
			)
		) {
			return new WP_Error(
				'tutorhelper_email_template_invalid',
				__(
					'The selected email template could not be found.',
					'tutorhelper-bookings'
				)
			);
		}

		$data =
			is_array( $data )
				? $data
				: array();

		$subject =
			isset( $data['subject'] )
				? sanitize_text_field(
					wp_unslash(
						$data['subject']
					)
				)
				: '';

		$body =
			isset( $data['body'] )
			&& ! is_array(
				$data['body']
			)
				? wp_kses_post(
					wp_unslash(
						$data['body']
					)
				)
				: '';

		if ( '' === trim( $subject ) ) {
			return new WP_Error(
				'tutorhelper_email_subject_missing',
				__(
					'Email subject is required.',
					'tutorhelper-bookings'
				)
			);
		}

		if ( '' === trim( $body ) ) {
			return new WP_Error(
				'tutorhelper_email_body_missing',
				__(
					'Email message is required.',
					'tutorhelper-bookings'
				)
			);
		}

		$saved =
			self::get_saved_overrides();

		$saved[ $template_key ] =
			array(
				'enabled' =>
					! empty(
						$data['enabled']
					),

				'subject' =>
					$subject,

				'body' =>
					$body,
			);

		update_option(
			self::OPTION_NAME,
			$saved,
			false
		);

		return true;
	}

	/**
	 * Restore one registered template to its defaults.
	 *
	 * @param string $template_key Template identifier.
	 *
	 * @return bool
	 */
	public static function restore_default(
		$template_key
	) {
		$template_key =
			sanitize_key(
				$template_key
			);

		if (
			! isset(
				self::$templates[
					$template_key
				]
			)
		) {
			return false;
		}

		$saved =
			self::get_saved_overrides();

		unset(
			$saved[ $template_key ]
		);

		if ( empty( $saved ) ) {
			delete_option(
				self::OPTION_NAME
			);

			return true;
		}

		update_option(
			self::OPTION_NAME,
			$saved,
			false
		);

		return true;
	}

	/**
	 * Return stored template overrides.
	 *
	 * @return array
	 */
	private static function get_saved_overrides() {
		$saved =
			get_option(
				self::OPTION_NAME,
				array()
			);

		return is_array( $saved )
			? $saved
			: array();
	}

	/**
	 * Merge permitted tutor overrides into a registered definition.
	 *
	 * @param array $default  Registered definition.
	 * @param array $override Stored tutor override.
	 *
	 * @return array
	 */
	private static function merge_template(
		$default,
		$override
	) {
		$template =
			$default;

		if (
			array_key_exists(
				'enabled',
				$override
			)
		) {
			$template['enabled'] =
				(bool) $override['enabled'];
		}

		if (
			isset( $override['subject'] )
			&& '' !== trim(
				(string) $override['subject']
			)
		) {
			$template['subject'] =
				sanitize_text_field(
					$override['subject']
				);
		}

		if (
			isset( $override['body'] )
			&& '' !== trim(
				(string) $override['body']
			)
		) {
			$template['body'] =
				wp_kses_post(
					$override['body']
				);
		}

		return $template;
	}

	/**
	 * Sanitise registered placeholder names.
	 *
	 * @param array $placeholders Raw placeholders.
	 *
	 * @return array
	 */
	private static function sanitize_placeholders(
		$placeholders
	) {
		if ( ! is_array( $placeholders ) ) {
			return array();
		}

		$clean = array();

		foreach ( $placeholders as $placeholder ) {
			$placeholder =
				trim(
					(string) $placeholder
				);

			if (
				! preg_match(
					'/^\{[a-z0-9_]+\}$/',
					$placeholder
				)
			) {
				continue;
			}

			if (
				! in_array(
					$placeholder,
					$clean,
					true
				)
			) {
				$clean[] =
					$placeholder;
			}
		}

		return $clean;
	}
}
