<?php
/**
 * Class to manage Spectra Extensions.
 *
 * @package Spectra
 */

namespace Spectra;

use Spectra\Extensions\Animations;
use Spectra\Extensions\ImageMask;
use Spectra\Extensions\ResponsiveConditions;
use Spectra\Extensions\ResponsiveControls;
use Spectra\Extensions\ZIndex;
use Spectra\Traits\Singleton;

defined( 'ABSPATH' ) || exit;

/**
 * Class to manage Spectra Extensions.
 *
 * @since 3.0.0-beta.1
 */
class ExtensionManager {

	use Singleton;

	/**
	 * Initializes the extension manager by registering all extensions.
	 *
	 * @since 3.0.0-beta.1
	 * @return void
	 */
	public function init() {
		$this->init_extensions();

		add_action( 'enqueue_block_editor_assets', array( $this, 'register_extensions' ) );
	}

	/**
	 * Initializes all extensions by calling their init() method.
	 *
	 * This method is used to trigger the initialization of all extensions.
	 * when the extension manager is initialized.
	 *
	 * @since 3.0.0-beta.1
	 * 
	 * @return void
	 */
	public function init_extensions() {
		( Animations::instance() )->init();
		( ImageMask::instance() )->init();
		( ResponsiveControls::instance() )->init();
		( ZIndex::instance() )->init();
		( ResponsiveConditions::instance() )->init();
	}

	/**
	 * Enqueues all extensions editor assets.
	 *
	 * This method scans the 'build/extensions/' directory for subdirectories containing
	 * an 'index.asset.php' file, and calls the enqueue_editor_extension_assets() method
	 * for each of them.
	 *
	 * @since 3.0.0-beta.1
	 * 
	 * @return void
	 */
	public function register_extensions() {
		$extensions_dir = SPECTRA_3_DIR . 'build/extensions/';

		if ( ! is_dir( $extensions_dir ) || ! is_readable( $extensions_dir ) ) {
			return;
		}

		$extension_files = glob( $extensions_dir . '*/index.asset.php' );

		if ( empty( $extension_files ) ) {
			return;
		}

		// Process all extensions.
		foreach ( $extension_files as $extension_file ) {
			$this->enqueue_editor_extension_assets( $extension_file );
		}
	}

	/**
	 * Enqueues editor assets for a given extension.
	 *
	 * @since 3.0.0-beta.1
	 *
	 * @param string $extension_file Path to the extension's asset file.
	 * @return void
	 */
	private function enqueue_editor_extension_assets( $extension_file ) {
		if ( ! file_exists( $extension_file ) ) {
			return;
		}

		$extension_dir = dirname( $extension_file );
		$folder_name   = basename( $extension_dir ); // Get extension folder name.
		$handle        = "spectra-3-extension-{$folder_name}-editor";
		$script_url    = SPECTRA_3_URL . "build/extensions/{$folder_name}/index.js";
		$script_path   = SPECTRA_3_DIR . "build/extensions/{$folder_name}/index.js";

		if ( ! file_exists( $script_path ) ) {
			return;
		}

		// Load the asset file generated by Webpack.
		$asset_file = include_once $extension_file;
		
		// Handle case where include_once returns true (already included).
		if ( true === $asset_file ) {
			$asset_file = array(
				'dependencies' => array(),
				'version'      => '1.0.0',
			);
		}
		
		// Ensure we have a valid asset file array.
		if ( ! is_array( $asset_file ) ) {
			return;
		}

		wp_enqueue_script(
			$handle,
			$script_url,
			isset( $asset_file['dependencies'] ) ? $asset_file['dependencies'] : array(),
			isset( $asset_file['version'] ) ? $asset_file['version'] : '1.0.0',
			true
		);

		// Localize script data for the image mask extension.
		if ( 'image-mask' === $folder_name ) {
			wp_localize_script(
				$handle,
				'spectraExtensions',
				array(
					'pluginUrl' => trailingslashit( SPECTRA_3_URL ),
					'assetsUrl' => trailingslashit( SPECTRA_3_URL ) . 'assets/',
				)
			);
		}

		/**
		 * Fires after enqueuing the editor assets for the given extension.
		 *
		 * The dynamic portion of the filter name is the extension folder name.
		 *
		 * @since 3.0.0-beta.1
		 */
		do_action( 'spectra_3_extensions_editor_assets', $folder_name, $asset_file );
	}
}
