<?php
/**
 * MenuX Free — Gutenberg Block (giuliomax/menu)
 *
 * Registers a native dynamic block that reuses the existing shortcode renderer
 * (menux_render_shortcode) without duplicating any HTML generation logic.
 *
 * @package MenuX
 */

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

add_action( 'init', 'menux_register_block' );

function menux_register_block() {
	/*
	 * block.json now uses "editorScript": "file:./editor.js" + editor.asset.php,
	 * so WordPress registers the script automatically with the correct dependencies.
	 * We only pass render_callback here because it cannot be expressed in JSON.
	 */
	register_block_type(
		MENUX_DIR . 'blocks/menux-menu',
		[ 'render_callback' => 'menux_block_render_callback' ]
	);
}

/**
 * Server-side render callback for giuliomax/menu.
 *
 * Delegates entirely to menux_render_shortcode() so the rendering logic
 * lives in exactly one place.  When multiple block instances appear on the
 * same page (or alongside a [menux] shortcode), fixed element IDs are given
 * a unique suffix to avoid conflicts; class-based selectors in frontend.js
 * (querySelectorAll('.menux-container')) already handle multiple navs safely.
 *
 * Overlay / close-button IDs are intentionally left alone: the shortcode's
 * static variable renders those only once regardless of instance count.
 *
 * @param array $attributes Block attributes.
 * @return string Rendered HTML.
 */
function menux_block_render_callback( $attributes ) {
	static $instance = 0;
	$instance++;

	$location = isset( $attributes['location'] ) ? sanitize_key( $attributes['location'] ) : 'primary';
	$html     = menux_render_shortcode( [ 'location' => $location ] );

	if ( empty( $html ) ) {
		return '';
	}

	/*
	 * ServerSideRender preview: Gutenberg fetches this via a REST API call and
	 * renders the result in an isolated Sandbox iframe. That iframe has no access
	 * to styles enqueued the normal way, so we prepend a <link> for Font Awesome
	 * and a <style> with the generated CSS directly into the returned HTML.
	 * On the real frontend REST_REQUEST is not defined, so normal asset loading
	 * takes over and there is no duplication.
	 */
	if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
		$style     = get_option( 'menux_style', array() );
		$css       = menux_generate_css( $style );
		if ( class_exists( 'Menux_Accessibility' ) ) {
			$css .= Menux_Accessibility::generate_css();
		}
		$fa6_url = MENUX_URL . 'assets/fa6/css/all.min.css';

		/*
		 * The Sandbox iframe is narrow, which triggers mobile breakpoints and hides
		 * the nav items behind the hamburger. Force desktop layout so the preview is
		 * representative of how the menu looks on a real page.
		 * Also disable entrance animations so items are visible immediately.
		 */
		$preview_css = '
			.menux-hamburger{display:none!important;}
			.menux-list{display:flex!important;flex-direction:row!important;flex-wrap:wrap!important;opacity:1!important;}
			.menux-list>li{display:list-item!important;opacity:1!important;animation:none!important;}
			.menux-container{display:flex!important;flex-direction:row!important;align-items:center!important;}
			.menux-is-mobile .menux-hamburger{display:none!important;}
			.menux-is-mobile .menux-list{display:flex!important;flex-direction:row!important;}
		';

		$prefix  = '<link rel="stylesheet" href="' . esc_url( $fa6_url ) . '">';
		$prefix .= '<style>' . wp_strip_all_tags( $css ) . wp_strip_all_tags( $preview_css ) . '</style>';

		return $prefix . $html;
	}

	/*
	 * Replace fixed structural IDs with a unique suffix so that multiple
	 * block instances (e.g. header + footer menu) don't share the same ID.
	 * We also update aria-controls references that point to the same IDs.
	 */
	$suffix       = 'blk' . $instance;
	$ids_to_fix   = [
		'menux-nav-main',
		'menux-list-main',
		'menux-spacer',
		'menux-progress-bar',
	];
	$search  = [];
	$replace = [];

	foreach ( $ids_to_fix as $id ) {
		$search[]  = 'id="' . $id . '"';
		$replace[] = 'id="' . $id . '-' . $suffix . '"';

		$search[]  = 'aria-controls="' . $id . '"';
		$replace[] = 'aria-controls="' . $id . '-' . $suffix . '"';
	}

	return str_replace( $search, $replace, $html );
}

/* ── Assets: editor iframe + Site Editor template preview ───────────── */

/**
 * Enqueues all MenuX front-end assets inside the block editor and the
 * Full Site Editor's iframe so that:
 *   • Font Awesome icons render correctly in InspectorControls / ServerSideRender
 *   • The configured Google Font is visible in the editor preview
 *   • Dynamic CSS (colors, layout, themes) is applied to the live preview
 *   • frontend.js initialises the mega menu and hamburger inside the
 *     Site Editor's template-part preview iframe
 */
add_action( 'enqueue_block_editor_assets', 'menux_enqueue_block_editor_assets' );

function menux_enqueue_block_editor_assets() {
	$style = get_option( 'menux_style', array() );

	/* Google Font — loaded only when configured (same guard as the frontend hook). */
	if ( ! empty( $style['google_font'] ) ) {
		$gf_slug = urlencode( $style['google_font'] );
		wp_enqueue_style(
			'menux-gfont',
			"https://fonts.googleapis.com/css2?family={$gf_slug}:wght@300;400;500;600;700&display=swap",
			array(),
			null
		);
	}

	/* Font Awesome 6 — required for item icons and mega menu headings. */
	wp_enqueue_style( 'menux-fa6', MENUX_URL . 'assets/fa6/css/all.min.css', array(), '6.5.2' );

	/* Dynamic CSS generated from saved style options. */
	$generated_css = menux_generate_css( $style );
	wp_add_inline_style( 'menux-fa6', wp_strip_all_tags( $generated_css ) );

	if ( class_exists( 'Menux_Accessibility' ) ) {
		$a11y_css = Menux_Accessibility::generate_css();
		wp_add_inline_style( 'menux-fa6', wp_strip_all_tags( $a11y_css ) );
	}

	/*
	 * Frontend JS — loaded in the editor so that the mega-menu hover behaviour
	 * and hamburger toggle work correctly inside the Site Editor's template
	 * preview iframe.  The config object mirrors what shortcode.php injects on
	 * the frontend via wp_add_inline_script().
	 */
	wp_enqueue_script( 'menux-frontend', MENUX_URL . 'assets/js/frontend.js', array(), MENUX_VERSION, true );

	$supported_langs = menux_get_supported_languages();
	$lang_codes      = empty( $supported_langs ) ? array( 'it-IT', 'en-US' ) : array_column( $supported_langs, 'code' );
	$default_lang    = ! empty( $lang_codes ) ? $lang_codes[0] : 'it-IT';
	$s               = wp_parse_args( $style, menux_style_defaults() );

	$frontend_data = wp_json_encode( array(
		'supportedCodes' => $lang_codes,
		'defaultCode'    => $default_lang,
		'ajaxUrl'        => admin_url( 'admin-ajax.php' ),
		'trackNonce'     => wp_create_nonce( 'menux_track_nonce' ),
		'isLoggedIn'     => is_user_logged_in() ? 1 : 0,
		'isSticky'       => isset( $s['sticky'] ) && $s['sticky'] === '1' ? 1 : 0,
		'searchEnabled'  => ! empty( $s['search_enabled'] ) && $s['search_enabled'] === '1',
		'a11y'           => class_exists( 'Menux_Accessibility' )
			? Menux_Accessibility::get_js_config( Menux_Accessibility::get_settings() )
			: array(),
	) );

	wp_add_inline_script( 'menux-frontend', 'window.menuxFrontendData = ' . $frontend_data . ';', 'before' );
}
