<?php
/**
 * Variable registry for Prompt Builder UI.
 *
 * @package AIPT\Api\PromptBuilder
 */

namespace AIPT\Api\PromptBuilder;

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

class VariableRegistry {
	public const GROUP_SYSTEM  = 'system';
	public const GROUP_PRODUCT = 'product';
	public const GROUP_CUSTOM  = 'custom';

	/**
	 * Singleton instance.
	 *
	 * @var self|null
	 */
	private static ?self $instance = null;

	/**
	 * Static variable definitions.
	 *
	 * @var array<int, array<string, string>>
	 */
	private array $definitions = array();

	public static function getInstance(): self {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	private function __construct() {
		$this->registerDefaults();
	}

	/**
	 * Prevent cloning to enforce the singleton guarantee.
	 *
	 * @return void
	 */
	private function __clone() {
	}

	/**
	 * Prevent unserialization to enforce the singleton guarantee.
	 *
	 * @throws \RuntimeException When unserialization is attempted.
	 * @return void
	 */
	public function __wakeup(): void {
		throw new \RuntimeException( 'Cannot unserialize singleton.' );
	}

	/**
	 * Get all registered variable definitions.
	 *
	 * @param string|null $group Optional group filter.
	 * @return array<int, array<string, string>>
	 */
	public function getDefinitions( ?string $group = null ): array {

		$builtin_placeholders = array();
		foreach ( $this->definitions as $definition ) {
			if ( isset( $definition['placeholder'] ) ) {
				$builtin_placeholders[ $definition['placeholder'] ] = true;
			}
		}

		$custom_definitions = array_values(
			array_filter(
				$this->getCustomDefinitions(),
				static function ( array $definition ) use ( $builtin_placeholders ): bool {
					return ! isset( $definition['placeholder'] )
						|| ! isset( $builtin_placeholders[ $definition['placeholder'] ] );
				}
			)
		);

		$definitions = array_merge( $this->definitions, $custom_definitions );

		if ( null === $group || '' === $group ) {
			return $definitions;
		}

		$group = sanitize_text_field( $group );

		return array_values(
			array_filter(
				$definitions,
				static function ( array $definition ) use ( $group ): bool {
					return isset( $definition['group'] ) && $group === $definition['group'];
				}
			)
		);
	}

	/**
	 * Build REST payload.
	 *
	 * @param string|null $group Optional group filter.
	 * @return array<string, array<int, array<string, mixed>>>
	 */
	public function toRestResponse( ?string $group = null ): array {
		$group = null === $group ? null : sanitize_text_field( $group );

		$groups = array(
			self::GROUP_SYSTEM  => __( 'General Variables', 'ai-product-tools' ),
			self::GROUP_PRODUCT => __( 'Product Variables', 'ai-product-tools' ),
			self::GROUP_CUSTOM  => __( 'Custom Variables', 'ai-product-tools' ),
		);

		$response_groups = array();

		foreach ( $groups as $group_key => $label ) {
			if ( null !== $group && '' !== $group && $group_key !== $group ) {
				continue;
			}

			$variables = array_map(
				static function ( array $definition ): array {
					unset( $definition['group'] );

					return $definition;
				},
				$this->getDefinitions( $group_key )
			);

			$response_groups[] = array(
				'key'       => $group_key,
				'label'     => $label,
				'variables' => array_values( $variables ),
			);
		}

		return array(
			'groups' => $response_groups,
		);
	}

	/**
	 * Register built-in variables.
	 *
	 * @return void
	 */
	private function registerDefaults(): void {
		$this->definitions = array(
			array(
				'key'         => 'language',
				'placeholder' => '{language}',
				'label'       => __( 'Language', 'ai-product-tools' ),
				'group'       => self::GROUP_SYSTEM,
				'description' => __( 'Target language for generated content.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'style',
				'placeholder' => '{style}',
				'label'       => __( 'Writing Style', 'ai-product-tools' ),
				'group'       => self::GROUP_SYSTEM,
				'description' => __( 'Selected writing style or tone.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'title',
				'placeholder' => '{title}',
				'label'       => __( 'Product Title', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The product display name.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'sku',
				'placeholder' => '{SKU}',
				'label'       => __( 'SKU', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The product SKU.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'attributes',
				'placeholder' => '{ATTRIBUTES}',
				'label'       => __( 'Attributes', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'Formatted product attributes.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'categories',
				'placeholder' => '{CATEGORIES}',
				'label'       => __( 'Categories', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The product categories.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'tags',
				'placeholder' => '{TAGS}',
				'label'       => __( 'Tags', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The product tags.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'price',
				'placeholder' => '{PRICE}',
				'label'       => __( 'Price', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The active display price.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'regular_price',
				'placeholder' => '{REGULAR_PRICE}',
				'label'       => __( 'Regular Price', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The regular product price.', 'ai-product-tools' ),
			),
			array(
				'key'         => 'sale_price',
				'placeholder' => '{SALE_PRICE}',
				'label'       => __( 'Sale Price', 'ai-product-tools' ),
				'group'       => self::GROUP_PRODUCT,
				'description' => __( 'The sale product price.', 'ai-product-tools' ),
			),
		);
	}

	/**
	 * Build custom variable definitions from saved settings.
	 *
	 * @return array<int, array<string, string>>
	 */
	private function getCustomDefinitions(): array {
		$variables    = get_option( 'aipt_custom_variables', array() );
		$definitions  = array();
		$placeholders = array();

		if ( ! is_array( $variables ) ) {
			return $definitions;
		}

		foreach ( $variables as $variable ) {
			if ( ! is_array( $variable ) || empty( $variable['name'] ) ) {
				continue;
			}

			$name = sanitize_text_field( (string) $variable['name'] );
			if ( '' === $name ) {
				continue;
			}

			$placeholder = '{' . $name . '}';
			if ( isset( $placeholders[ $placeholder ] ) ) {
				continue;
			}

			$placeholders[ $placeholder ] = true;

			$definitions[] = array(
				'key'         => $name,
				'placeholder' => $placeholder,
				'label'       => $name,
				'group'       => self::GROUP_CUSTOM,
				'description' => __( 'Custom variable defined in settings.', 'ai-product-tools' ),
			);
		}

		return $definitions;
	}
}
