<?php
/**
 * Gutenberg block server-side loader.
 *
 * @package    100Prints
 */

class Hundred_Prints_Block_Loader {

	/**
	 * Register SDK scripts shared by the editor, frontend, shortcode, and admin previews.
	 */
	private function register_sdk_assets() {
		$sdk_path    = HUNDRED_PRINTS_PATH . 'assets/js/wordpress-sdk.umd.js';
		$compat_path = HUNDRED_PRINTS_PATH . 'assets/js/sdk-compat.js';

		wp_register_script(
			'100prints-sdk',
			HUNDRED_PRINTS_URL . 'assets/js/wordpress-sdk.umd.js',
			[],
			file_exists( $sdk_path ) ? filemtime( $sdk_path ) : HUNDRED_PRINTS_VERSION,
			true
		);
		wp_script_add_data( '100prints-sdk', 'defer', true );

		wp_register_script(
			'100prints-sdk-compat',
			HUNDRED_PRINTS_URL . 'assets/js/sdk-compat.js',
			[ '100prints-sdk' ],
			file_exists( $compat_path ) ? filemtime( $compat_path ) : HUNDRED_PRINTS_VERSION,
			true
		);
		wp_script_add_data( '100prints-sdk-compat', 'defer', true );
	}

	/**
	 * Add an extra dependency to a script that WordPress registered from block metadata.
	 *
	 * @param string $handle     Registered script handle.
	 * @param string $dependency Dependency handle.
	 */
	private function add_script_dependency( $handle, $dependency ) {
		global $wp_scripts;

		if ( ! $wp_scripts || empty( $wp_scripts->registered[ $handle ] ) ) {
			return;
		}

		if ( ! in_array( $dependency, $wp_scripts->registered[ $handle ]->deps, true ) ) {
			$wp_scripts->registered[ $handle ]->deps[] = $dependency;
		}
	}

	/**
	 * Localize editor defaults for newly inserted blocks.
	 */
	private function localize_editor_settings() {
		if ( wp_script_is( 'hundredprints-document-editor-script', 'registered' ) ) {
			$editor_settings = hundred_prints_get_public_settings();
			$editor_settings['variableMappingSources'] = hundred_prints_get_variable_mapping_sources();

			wp_localize_script(
				'hundredprints-document-editor-script',
				'hundredPrintsSettings',
				$editor_settings
			);
		}
	}

	/**
	 * Register Gutenberg blocks.
	 */
	public function register_blocks() {
		if ( ! function_exists( 'register_block_type' ) ) {
			return;
		}

		$this->register_sdk_assets();

		// Register the block from the compiled build directory.
		$result = register_block_type( HUNDRED_PRINTS_PATH . 'build/blocks/document' );
		if ( is_wp_error( $result ) ) {
			error_log( '100Prints Block Registration Error (document): ' . $result->get_error_message() );
		}

		$result_form = register_block_type( HUNDRED_PRINTS_PATH . 'build/blocks/form' );
		if ( is_wp_error( $result_form ) ) {
			error_log( '100Prints Block Registration Error (form): ' . $result_form->get_error_message() );
		}

		$this->add_script_dependency( 'hundredprints-document-editor-script', '100prints-sdk-compat' );
		$this->add_script_dependency( 'hundredprints-document-script', '100prints-sdk-compat' );
		$this->add_script_dependency( 'hundredprints-document-view-script', '100prints-sdk-compat' );
		$this->localize_editor_settings();
	}

	/**
	 * Enqueue SDK/runtime dependencies and expose frontend data.
	 */
	private function enqueue_runtime_assets() {
		$this->register_sdk_assets();
		// CSS icons (Phosphor)
		wp_enqueue_style( 'phosphor-icons', HUNDRED_PRINTS_URL . 'assets/admin/vendors/phosphor-icons/css/icons.css', [], '1.4.2' );
		wp_enqueue_style( 'dashicons' );

		wp_enqueue_script( '100prints-sdk-compat' );
	}

	/**
	 * Provide localized data to the frontend runtime.
	 */
	private function localize_frontend_data() {
		wp_localize_script( '100prints-sdk-compat', 'hundredPrintsData', [
			'restUrl' => esc_url_raw( rest_url( '100prints/v1/' ) ),
			'nonce'   => wp_create_nonce( 'wp_rest' ),
			'postId'  => get_the_ID() ?: 0,
			'userId'  => get_current_user_id(),
			'pluginUrl' => HUNDRED_PRINTS_URL,
			'settings' => hundred_prints_get_public_settings(),
			'debugMode' => (bool) hundred_prints_get_settings()['debug_mode'],
		] );
	}

	/**
	 * Enqueue global dependencies that the block relies on.
	 */
	public function enqueue_frontend_assets() {
		if ( ! has_block( 'hundredprints/document' ) ) {
			return;
		}

		$this->enqueue_runtime_assets();
		$this->localize_frontend_data();
	}

	/**
	 * Preload SDK scripts globally when enabled in settings.
	 */
	public function enqueue_global_sdk_assets() {
		if ( is_admin() || has_block( 'hundredprints/document' ) ) {
			return;
		}

		if ( empty( hundred_prints_get_settings()['preload_sdk_globally'] ) ) {
			return;
		}

		$this->enqueue_runtime_assets();
		$this->localize_frontend_data();
	}

	/**
	 * Force enqueue frontend assets for shortcode rendering.
	 */
	public function force_enqueue_frontend_assets() {
		$this->enqueue_runtime_assets();

		if ( wp_script_is( 'hundredprints-document-script', 'registered' ) ) {
			wp_enqueue_script( 'hundredprints-document-script' );
		} else {
			$view_path = HUNDRED_PRINTS_PATH . 'build/blocks/document/view.js';
			wp_enqueue_script(
				'hundredprints-document-script',
				HUNDRED_PRINTS_URL . 'build/blocks/document/view.js',
				[ '100prints-sdk-compat' ],
				file_exists( $view_path ) ? filemtime( $view_path ) : HUNDRED_PRINTS_VERSION,
				true
			);
		}

		if ( wp_style_is( 'hundredprints-document-style', 'registered' ) ) {
			wp_enqueue_style( 'hundredprints-document-style' );
		} else {
			$style_path = HUNDRED_PRINTS_PATH . 'build/blocks/document/style-index.css';
			wp_enqueue_style(
				'hundredprints-document-style',
				HUNDRED_PRINTS_URL . 'build/blocks/document/style-index.css',
				[],
				file_exists( $style_path ) ? filemtime( $style_path ) : HUNDRED_PRINTS_VERSION
			);
		}

		$this->localize_frontend_data();
	}
}
