<?php

namespace SugarCalendarBookings\BookingForm;

use SugarCalendarBookings\Admin\Assets;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Blocks\AbstractBlock;
use WP_Block;

/**
 * Booking Form Block.
 *
 * Handles the registration and rendering of the booking form Gutenberg block.
 *
 * @since 1.0.0
 */
class BookingFormBlock extends AbstractBlock {

	/**
	 * Get the block name (slug).
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public function get_block_name(): string {

		return 'scbookings/booking-form';
	}

	/**
	 * Register the booking form block.
	 *
	 * @since 1.0.0
	 */
	public function register(): void {

		if ( ! $this->allow_load() ) {
			return;
		}

		register_block_type(
			SCBOOKINGS_PLUGIN_PATH . 'assets/dist/booking-form',
			[
				'render_callback' => [ $this, 'display' ],
			]
		);
	}

	/**
	 * Render the booking form block.
	 *
	 * @since 1.0.0
	 * @since 1.2.0 Add check to not display the block if no services are found and not in admin.
	 *
	 * @param array    $attributes Block attributes.
	 * @param string   $content    Block default content.
	 * @param WP_Block $block      Block instance.
	 *
	 * @return string Block HTML output.
	 */
	public function display( array $attributes, string $content, $block ): string {

		// Get service IDs from block attributes.
		$service_ids = $attributes['services'] ?? [];

		// Get booking form data using the controller.
		$booking_form_data = Plugin::get( BookingFormService::class )->get_booking_form_data( $service_ids );

		// If no services are found and not in admin, don't display the block.
		if (
			empty( $booking_form_data['services'] )
			&&
			! is_admin()
		) {
			return '';
		}

		// Add the booking form data to attributes for the markup.
		$attributes['initialData'] = $booking_form_data;

		ob_start();

		$this->output_markup( $attributes );

		return ob_get_clean();
	}

	/**
	 * Output the booking form markup.
	 *
	 * @since 1.0.0
	 *
	 * @param array $attributes Block attributes.
	 */
	private function output_markup( $attributes ) {

		$wrapper_attributes = get_block_wrapper_attributes(
            [
				'class' => 'scbookings-sc-bookings-form',
            ]
        );
		$attributes_json    = wp_json_encode( $attributes );
		$attributes_data    = _wp_specialchars( $attributes_json, ENT_QUOTES, 'UTF-8', true );
		?>

		<div <?php echo $wrapper_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
			<div
				class="scbookings-sc-bookings-form-container"
				data-block-data="<?php echo $attributes_data; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>"
			>
			</div>
		</div>
		<?php
	}

	/**
	 * Enqueue block editor assets and localize script data.
	 *
	 * @since 1.0.0
	 */
	public function enqueue_editor_assets(): void {

		// Only enqueue if this block should be loaded.
		if ( ! $this->allow_load() ) {
			return;
		}

		$this->register_react_jsx_runtime();

		$handle = ! Plugin::get( Assets::class )->is_dev() ? 'scbookings-booking-form-script' : 'undefined-booking-form/frontend';

		// Localize script data for blocks.
		wp_localize_script(
			$handle,
			'sugar_calendar_bookings',
			Plugin::get( BookingFormService::class )->get_script_data()
		);
	}

	/**
	 * Enqueue view assets and localize script data.
	 *
	 * @since 1.0.0
	 * @since 1.5.0 Enqueue antispam captcha script when a provider is configured.
	 */
	public function enqueue_view_assets(): void {

		// Only enqueue if this block should be loaded and is present on the page.
		if ( ! $this->allow_load() || ! has_block( $this->get_block_name() ) ) {
			return;
		}

		$this->register_react_jsx_runtime();

		$handle = ! Plugin::get( Assets::class )->is_dev() ? 'scbookings-booking-form-script' : 'undefined-booking-form/frontend';

		// Localize script data for the view script.
		wp_localize_script(
			$handle,
			'sugar_calendar_bookings',
			Plugin::get( BookingFormService::class )->get_script_data()
		);

		// Enqueue antispam captcha script if a provider is configured.
		Plugin::get( BookingFormAssets::class )->enqueue_antispam_third_party_script();
	}

	/**
	 * Register the React JSX runtime if not available in older WordPress versions.
	 *
	 * @since 1.0.0
	 */
	private function register_react_jsx_runtime(): void {

		if ( ! wp_script_is( 'react-jsx-runtime', 'registered' ) ) {
			wp_register_script(
				'react-jsx-runtime',
				SCBOOKINGS_PLUGIN_URL . 'assets/lib/react-jsx-runtime.js',
				[ 'react' ],
				'18.3.1',
				true
			);
		}
	}
}
