<?php
/**
 * Dynamic Gutenberg block and editor script registrar.
 *
 * @package PDFDraft
 */

namespace PDFDraft\Blocks;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Generic registrar for server and editor block definitions.
 */
class BlockRegistrar {
	/**
	 * Register server-rendered block definitions.
	 *
	 * @param array<int, array{name:string,args:array}> $definitions Block definitions.
	 * @return void
	 */
	public function registerBlocks( array $definitions ): void {
		foreach ( $definitions as $definition ) {
			$name = (string) ( $definition['name'] ?? '' );
			$args = (array) ( $definition['args'] ?? array() );
			if ( '' === $name ) {
				continue;
			}
			register_block_type( $name, $args );
		}
	}

	/**
	 * Register and enqueue block editor scripts from definitions.
	 *
	 * @param array<int, array<string,mixed>> $definitions Script definitions.
	 * @return void
	 */
	public function registerAndEnqueueEditorScripts( array $definitions ): void {
		foreach ( $definitions as $definition ) {
			$handle = (string) ( $definition['handle'] ?? '' );
			$src    = (string) ( $definition['src'] ?? '' );
			if ( '' === $handle || '' === $src ) {
				continue;
			}
			$asset_file = (string) ( $definition['asset_file'] ?? '' );
			$asset      = $this->getAssetMeta( $asset_file );
			$deps       = array_values(
				array_unique(
					array_merge(
						(array) ( $asset['dependencies'] ?? array() ),
						(array) ( $definition['deps'] ?? array() )
					)
				)
			);
			$version    = (string) ( $asset['version'] ?? ( $definition['version'] ?? PDFDRAFT_VERSION ) );

			wp_deregister_script( $handle );
			wp_register_script( $handle, $src, $deps, $version, true );
			wp_enqueue_script( $handle );

			$before_inline = (string) ( $definition['before_inline'] ?? '' );
			if ( '' !== $before_inline ) {
				wp_add_inline_script( $handle, $before_inline, 'before' );
			}

			$localize_object = (string) ( $definition['localize_object'] ?? '' );
			$localize_data   = (array) ( $definition['localize_data'] ?? array() );
			if ( '' !== $localize_object && ! empty( $localize_data ) ) {
				wp_localize_script( $handle, $localize_object, $localize_data );
			}
		}
	}

	/**
	 * Read and normalize a WordPress asset metadata file.
	 *
	 * @param string $asset_file Asset metadata file path.
	 * @return array{dependencies:array,version:string}
	 */
	private function getAssetMeta( string $asset_file ): array {
		if ( '' !== $asset_file && file_exists( $asset_file ) ) {
			$asset = include $asset_file;
			if ( is_array( $asset ) ) {
				return array(
					'dependencies' => (array) ( $asset['dependencies'] ?? array() ),
					'version'      => (string) ( $asset['version'] ?? PDFDRAFT_VERSION ),
				);
			}
		}

		return array(
			'dependencies' => array(),
			'version'      => PDFDRAFT_VERSION,
		);
	}
}
