<?php
/**
 * Event Templates registry
 *
 * Code-defined catalog of per-event visual design templates. Each template
 * is a named bundle of default values for the 13 styling tokens. The admin
 * editor (EventStylingEditor.js) reads this catalog via wp_localize_script;
 * the frontend never needs it because templates are resolved to concrete
 * tokens at save time (Event_Creator::sanitize_styling()).
 *
 * @package NemtlyBooking
 */

namespace NemtlyBooking\Core;

/**
 * Event_Templates class
 *
 * Source of truth for:
 *  - The set of allowed styling tokens and their valid enum values.
 *  - The 6 built-in templates (Mono, Bold, Warm, Ocean, Forest, Festive).
 *
 * Extensibility: the `nemtly_booking_event_templates` filter lets third parties
 * register additional templates. Each template must declare all 17 tokens.
 *
 * @since PBOOKING_SINCE
 */
class Event_Templates {

	/**
	 * Color tokens — sanitized via sanitize_hex_color(), stored as hex or ''.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @var string[]
	 */
	const COLOR_KEYS = [
		'header_background',
		'header_title_text',
		'tag_text',
		'tag_background',
		'detail_text',
		'price_text',
		'button_background',
		'button_text',
		'card_background',
		'border_color',
	];

	/**
	 * Enum tokens and their allowed values. '' means "inherit default".
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @var array<string, string[]>
	 */
	const ENUM_VALUES = [
		'card_radius'    => [ '', 'sharp', 'rounded', 'pill' ],
		'button_radius'  => [ '', 'sharp', 'rounded', 'pill' ],
		'shadow'         => [ '', 'none', 'low', 'medium', 'high' ],
		'spacing'        => [ '', 'compact', 'normal', 'loose' ],
		'heading_size'   => [ '', 'sm', 'md', 'lg' ],
		'heading_weight' => [ '', 'normal', 'medium', 'semibold', 'bold' ],
	];

	/**
	 * The complete list of all styling token keys (colors + enums).
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @var string[]
	 */
	const ALL_TOKEN_KEYS = [
		'header_background',
		'header_title_text',
		'tag_text',
		'tag_background',
		'detail_text',
		'price_text',
		'button_background',
		'button_text',
		'card_background',
		'border_color',
		'card_radius',
		'button_radius',
		'shadow',
		'spacing',
		'heading_size',
		'heading_weight',
	];

	/**
	 * The 6 built-in templates.
	 *
	 * Each template declares a human label, a short description, and a full
	 * set of 17 token defaults. Values reuse the palette families defined in
	 * tailwind.config.js wherever possible (Warm uses the dedicated warm family).
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @var array<string, array{label: string, description: string, tokens: array<string, string>}>
	 */
	const TEMPLATES = [
		'mono'    => [
			'label'       => 'Mono',
			'description' => 'Clean near-black on white — the default look.',
			'tokens'      => [
				'header_background' => '#252525',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#5B5B62',
				'price_text'        => '#0F0F10',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FFFFFF',
				'border_color'      => '#E7E5DF',
				'card_radius'       => 'rounded',
				'button_radius'     => 'rounded',
				'shadow'            => 'low',
				'spacing'           => 'normal',
				'heading_size'      => 'md',
				'heading_weight'    => 'semibold',
			],
		],
		'bold'    => [
			'label'       => 'Bold',
			'description' => 'High-contrast, hard borders, sharp corners — maximal punch.',
			'tokens'      => [
				'header_background' => '#0F0F10',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#5B5B62',
				'price_text'        => '#0F0F10',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FFFFFF',
				'border_color'      => '#0F0F10',
				'card_radius'       => 'sharp',
				'button_radius'     => 'sharp',
				'shadow'            => 'none',
				'spacing'           => 'compact',
				'heading_size'      => 'lg',
				'heading_weight'    => 'bold',
			],
		],
		'warm'    => [
			'label'       => 'Warm',
			'description' => 'Earthy cream and brown — soft, generous, suited to wellness and studio brands.',
			'tokens'      => [
				'header_background' => '#92632A',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#7A6B50',
				'price_text'        => '#2D2416',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FBF8F3',
				'border_color'      => '#E7DDC9',
				'card_radius'       => 'rounded',
				'button_radius'     => 'pill',
				'shadow'            => 'low',
				'spacing'           => 'loose',
				'heading_size'      => 'md',
				'heading_weight'    => 'medium',
			],
		],
		'ocean'   => [
			'label'       => 'Ocean',
			'description' => 'Calm blue on white — trustworthy and professional.',
			'tokens'      => [
				'header_background' => '#1D4ED8',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#5B5B62',
				'price_text'        => '#0F0F10',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FFFFFF',
				'border_color'      => '#EFF6FF',
				'card_radius'       => 'rounded',
				'button_radius'     => 'rounded',
				'shadow'            => 'medium',
				'spacing'           => 'normal',
				'heading_size'      => 'md',
				'heading_weight'    => 'semibold',
			],
		],
		'forest'  => [
			'label'       => 'Forest',
			'description' => 'Natural green — grounded, suited to education and outdoor events.',
			'tokens'      => [
				'header_background' => '#16794B',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#5B5B62',
				'price_text'        => '#0F0F10',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FFFFFF',
				'border_color'      => '#EDFCF3',
				'card_radius'       => 'rounded',
				'button_radius'     => 'pill',
				'shadow'            => 'low',
				'spacing'           => 'normal',
				'heading_size'      => 'md',
				'heading_weight'    => 'semibold',
			],
		],
		'festive' => [
			'label'       => 'Festive',
			'description' => 'Vibrant amber, pill shapes, bold type — energetic, for events and fitness.',
			'tokens'      => [
				'header_background' => '#D97706',
				'header_title_text' => '#FFFFFF',
				'tag_text'          => '#FFFFFF',
				'tag_background'    => '',
				'detail_text'       => '#5B5B62',
				'price_text'        => '#0F0F10',
				'button_background' => '',
				'button_text'       => '#FFFFFF',
				'card_background'   => '#FFFFFF',
				'border_color'      => '#FFFBEB',
				'card_radius'       => 'rounded',
				'button_radius'     => 'pill',
				'shadow'            => 'medium',
				'spacing'           => 'normal',
				'heading_size'      => 'lg',
				'heading_weight'    => 'bold',
			],
		],
	];

	/**
	 * Get all registered templates, including extensions via the filter.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @return array<string, array{label: string, description: string, tokens: array<string, string>}> Template catalog keyed by id.
	 */
	public static function get_all() {
		/**
		 * Filter the catalog of event design templates.
		 *
		 * Third parties can register additional templates. Each must declare
		 * a 'label', 'description', and a full 'tokens' array covering all
		 * keys listed in ALL_TOKEN_KEYS.
		 *
		 * @since PBOOKING_SINCE
		 *
		 * @param array $templates Template catalog keyed by template id.
		 */
		return apply_filters( 'nemtly_booking_event_templates', self::TEMPLATES );
	}

	/**
	 * Get a single template by id.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param string $id Template id (e.g. 'warm').
	 *
	 * @return array{label: string, description: string, tokens: array<string, string>}|null Template data or null if not found.
	 */
	public static function get( $id ) {
		$templates = self::get_all();
		return $templates[ $id ] ?? null;
	}

	/**
	 * Get the default token values for a template.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param string $id Template id.
	 *
	 * @return array<string, string> Token defaults, or the Mono defaults if the id is unknown.
	 */
	public static function get_defaults( $id ) {
		$template = self::get( $id );
		if ( $template && isset( $template['tokens'] ) ) {
			return $template['tokens'];
		}
		// Fall back to Mono — guarantees a complete token set is always returned.
		return self::TEMPLATES['mono']['tokens'];
	}

	/**
	 * Check whether a template id is registered.
	 *
	 * @since PBOOKING_SINCE
	 *
	 * @param string $id Template id.
	 *
	 * @return bool
	 */
	public static function exists( $id ) {
		return null !== self::get( $id );
	}
}
