<?php
/**
 * Front-end visual editor – Divi-style click-to-edit on the live page.
 *
 * @package EasySite_Pro
 */

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

/**
 * Is the visual editor active on this request?
 *
 * @return bool
 */
function easysite_ve_active() {
	return ! empty( $GLOBALS['easysite_ve_active'] );
}

/**
 * Should we load the visual editor for the current page?
 *
 * @return bool
 */
function easysite_ve_should_load() {
	if ( ! isset( $_GET['easysite_edit'] ) || '1' !== $_GET['easysite_edit'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return false;
	}
	if ( ! is_user_logged_in() ) {
		return false;
	}
	$post_id = easysite_ve_get_editable_post_id();
	if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
		return false;
	}
	return true;
}

/**
 * Get post ID being visually edited.
 *
 * @return int
 */
function easysite_ve_get_editable_post_id() {
	if ( is_singular( 'page' ) ) {
		return (int) get_queried_object_id();
	}
	if ( is_front_page() ) {
		$front = (int) get_option( 'page_on_front' );
		if ( $front ) {
			return $front;
		}
	}
	return 0;
}

/**
 * Editable attribute string for front-end elements.
 *
 * @param string $field Field key.
 * @param string $type  text|textarea|image|bg-image|url|button.
 * @return string
 */
function easysite_ve_attr( $field, $type = 'text' ) {
	if ( ! easysite_ve_active() ) {
		return '';
	}
	$attrs = array(
		'data-esb-field' => $field,
		'data-esb-type'  => $type,
	);
	if ( in_array( $type, array( 'text', 'textarea' ), true ) ) {
		$attrs['contenteditable'] = 'true';
		$attrs['spellcheck']      = 'true';
	}
	$out = '';
	foreach ( $attrs as $key => $val ) {
		$out .= ' ' . $key . '="' . esc_attr( $val ) . '"';
	}
	return $out;
}

/**
 * Display value or placeholder when editing.
 *
 * @param string $value       Stored value.
 * @param string $placeholder Placeholder when empty in edit mode.
 * @return string
 */
function easysite_ve_display( $value, $placeholder = '' ) {
	if ( $value ) {
		return $value;
	}
	return easysite_ve_active() ? $placeholder : '';
}

/**
 * Prepare page for visual editing (enable builder, migrate if needed).
 *
 * @param int $post_id Post ID.
 */
function easysite_ve_prepare_page( $post_id ) {
	update_post_meta( $post_id, EASYSITE_BUILDER_ENABLED, '1' );

	$layout = easysite_get_builder_layout( $post_id );
	if ( ! empty( $layout ) ) {
		return;
	}

	$layout = easysite_ve_migrate_homepage_layout();
	if ( empty( $layout ) ) {
		$layout = apply_filters( 'easysite_get_builder_layout_filter', array(), $post_id );
	}

	if ( ! empty( $layout ) ) {
		update_post_meta( $post_id, EASYSITE_BUILDER_META, wp_json_encode( $layout ) );
	}
}

/**
 * Build builder layout from customizer homepage mods.
 *
 * @return array
 */
function easysite_ve_migrate_homepage_layout() {
	$hero_title = easysite_get_mod( 'easysite_hero_title' );
	if ( ! $hero_title ) {
		return array();
	}

	return array(
		array(
			'id'     => 'esb_migrated_hero',
			'type'   => 'hero',
			'fields' => array(
				'title'       => $hero_title,
				'subtitle'    => easysite_get_mod( 'easysite_hero_subtitle' ),
				'button_text' => easysite_get_mod( 'easysite_hero_button_text' ),
				'button_url'  => easysite_get_mod( 'easysite_hero_button_link', '/contact' ),
				'bg_image'    => easysite_get_mod( 'easysite_hero_bg_image' ),
				'style'       => 'gradient-overlay',
				'gradient'    => 'brand',
			),
		),
		array(
			'id'     => 'esb_migrated_about',
			'type'   => 'image_text',
			'fields' => array(
				'title'   => easysite_get_mod( 'easysite_about_title', __( 'About Us', 'easysite-pro' ) ),
				'content' => easysite_get_mod( 'easysite_about_text' ),
				'image'   => easysite_get_mod( 'easysite_about_image' ),
				'layout'  => 'right',
			),
		),
		array(
			'id'     => 'esb_migrated_services',
			'type'   => 'services',
			'fields' => array(
				'title'        => easysite_get_mod( 'easysite_services_title', __( 'Our Services', 'easysite-pro' ) ),
				'item1_title'  => easysite_get_mod( 'easysite_service_1_title' ),
				'item1_text'   => easysite_get_mod( 'easysite_service_1_desc' ),
				'item1_price'  => easysite_get_mod( 'easysite_service_1_price' ),
				'item2_title'  => easysite_get_mod( 'easysite_service_2_title' ),
				'item2_text'   => easysite_get_mod( 'easysite_service_2_desc' ),
				'item2_price'  => easysite_get_mod( 'easysite_service_2_price' ),
				'item3_title'  => easysite_get_mod( 'easysite_service_3_title' ),
				'item3_text'   => easysite_get_mod( 'easysite_service_3_desc' ),
				'item3_price'  => easysite_get_mod( 'easysite_service_3_price' ),
			),
		),
		array(
			'id'     => 'esb_migrated_cta',
			'type'   => 'cta',
			'fields' => array(
				'title'       => __( 'Ready to get started?', 'easysite-pro' ),
				'subtitle'    => __( 'Contact us today.', 'easysite-pro' ),
				'button_text' => easysite_get_mod( 'easysite_hero_button_text', __( 'Contact Us', 'easysite-pro' ) ),
				'button_url'  => '/contact',
				'style'       => 'gradient',
				'gradient'    => 'brand',
			),
		),
	);
}

/**
 * Activate visual editor mode.
 */
function easysite_ve_bootstrap() {
	if ( ! easysite_ve_should_load() ) {
		return;
	}

	$post_id = easysite_ve_get_editable_post_id();
	easysite_ve_prepare_page( $post_id );

	$GLOBALS['easysite_ve_active'] = true;
	$GLOBALS['easysite_ve_post_id'] = $post_id;

	add_filter( 'body_class', function ( $classes ) {
		$classes[] = 'easysite-visual-editing';
		return $classes;
	} );

	add_action( 'wp_enqueue_scripts', 'easysite_ve_enqueue_assets', 100 );
	add_action( 'wp_footer', 'easysite_ve_render_shell', 5 );
}
add_action( 'template_redirect', 'easysite_ve_bootstrap', 1 );

/**
 * Enqueue visual editor assets.
 */
function easysite_ve_enqueue_assets() {
	$post_id = easysite_ve_get_editable_post_id();

	wp_enqueue_media();
	wp_enqueue_script( 'jquery-ui-sortable' );

	wp_enqueue_style(
		'easysite-visual-editor',
		EASYSITE_PRO_URI . '/assets/css/visual-editor.css',
		array( 'easysite-page-builder', 'easysite-pro-main' ),
		EASYSITE_PRO_VERSION
	);

	wp_enqueue_script(
		'easysite-visual-editor',
		EASYSITE_PRO_URI . '/assets/js/visual-editor.js',
		array( 'jquery', 'jquery-ui-sortable', 'media-editor' ),
		EASYSITE_PRO_VERSION,
		true
	);

	$registry = easysite_builder_section_registry();
	$public_registry = array();
	foreach ( $registry as $type => $def ) {
		$public_registry[ $type ] = array(
			'label'       => $def['label'],
			'description' => $def['description'],
			'icon'        => $def['icon'],
			'fields'      => $def['fields'],
		);
	}

	wp_enqueue_script(
		'easysite-visual-editor-extras',
		EASYSITE_PRO_URI . '/assets/js/visual-editor-extras.js',
		array( 'easysite-visual-editor' ),
		EASYSITE_PRO_VERSION,
		true
	);

	$user_id = get_current_user_id();
	$show_tour = $user_id && ! get_user_meta( $user_id, 'easysite_ve_tour_done', true );

	wp_localize_script( 'easysite-visual-editor', 'easysiteVE', array(
		'postId'          => $post_id,
		'layout'          => easysite_get_builder_layout( $post_id ),
		'registry'        => $public_registry,
		'designFields'    => easysite_get_design_field_defs(),
		'spacingMap'      => easysite_get_spacing_map(),
		'headerLayout'    => easysite_get_header_layout(),
		'headerElements'  => easysite_header_elements(),
		'footerLayout'    => easysite_get_footer_layout(),
		'regionMods'      => array(
			'header_button_text' => easysite_get_mod( 'easysite_header_button_text', __( 'Contact', 'easysite-pro' ) ),
			'header_button_link' => easysite_get_mod( 'easysite_header_button_link', '/contact' ),
			'footer_text'        => easysite_get_mod( 'easysite_footer_text', '' ),
			'site_title'         => get_bloginfo( 'name' ),
			'logo_id'            => get_theme_mod( 'custom_logo', 0 ),
			'popup_title'        => easysite_get_mod( 'easysite_popup_title', '' ),
			'popup_text'         => easysite_get_mod( 'easysite_popup_text', '' ),
			'popup_button'       => easysite_get_mod( 'easysite_popup_button_text', '' ),
			'form_label_name'    => easysite_get_mod( 'easysite_form_label_name', __( 'Your name', 'easysite-pro' ) ),
			'form_label_email'   => easysite_get_mod( 'easysite_form_label_email', __( 'Email', 'easysite-pro' ) ),
			'form_label_message' => easysite_get_mod( 'easysite_form_label_message', __( 'Message', 'easysite-pro' ) ),
			'form_label_submit'  => easysite_get_mod( 'easysite_form_label_submit', __( 'Send Message', 'easysite-pro' ) ),
		),
		'brandName'       => easysite_get_brand_name(),
		'seo'             => array(
			'title'       => is_singular() ? get_post_meta( get_queried_object_id(), '_easysite_seo_title', true ) : '',
			'description' => is_singular() ? get_post_meta( get_queried_object_id(), '_easysite_seo_description', true ) : '',
		),
		'canExport'       => current_user_can( 'edit_theme_options' ),
		'globalSections'  => easysite_get_global_sections(),
		'pageTemplates'   => easysite_ve_page_templates(),
		'sectionPresets'  => function_exists( 'easysite_section_presets_for_js' ) ? easysite_section_presets_for_js() : array(),
		'canUseLiveAi'    => function_exists( 'easysite_ai_uses_live_api' ) && easysite_ai_uses_live_api(),
		'brandColors'     => array(
			'main'   => easysite_get_mod( 'easysite_main_color', '#2563eb' ),
			'accent' => easysite_get_mod( 'easysite_accent_color', '#7c3aed' ),
		),
		'popup'           => array(
			'enabled' => easysite_get_mod( 'easysite_popup_enabled', false ),
			'title'   => easysite_get_mod( 'easysite_popup_title', '' ),
			'text'    => easysite_get_mod( 'easysite_popup_text', '' ),
			'button'  => easysite_get_mod( 'easysite_popup_button_text', '' ),
		),
		'showTour'        => $show_tour,
		'ajaxUrl'         => admin_url( 'admin-ajax.php' ),
		'nonce'           => wp_create_nonce( 'easysite_ve_nonce' ),
		'exitUrl'         => remove_query_arg( 'easysite_edit' ),
		'siteSettingsUrl' => admin_url( 'admin.php?page=easysite-site-settings' ),
		'i18n'            => array(
			'save'           => __( 'Save changes', 'easysite-pro' ),
			'saving'         => __( 'Saving…', 'easysite-pro' ),
			'saved'          => __( 'Saved!', 'easysite-pro' ),
			'exit'           => __( 'Exit editor', 'easysite-pro' ),
			'addSection'     => __( 'Add section', 'easysite-pro' ),
			'settings'       => __( 'Section settings', 'easysite-pro' ),
			'design'         => __( 'Design', 'easysite-pro' ),
			'content'        => __( 'Content', 'easysite-pro' ),
			'changeImage'    => __( 'Change image', 'easysite-pro' ),
			'changeBg'       => __( 'Change background', 'easysite-pro' ),
			'changeLogo'     => __( 'Change logo', 'easysite-pro' ),
			'remove'         => __( 'Remove section', 'easysite-pro' ),
			'duplicate'      => __( 'Duplicate', 'easysite-pro' ),
			'moveUp'         => __( 'Move up', 'easysite-pro' ),
			'moveDown'       => __( 'Move down', 'easysite-pro' ),
			'close'          => __( 'Close', 'easysite-pro' ),
			'pickSection'    => __( 'Choose a section to add', 'easysite-pro' ),
			'error'          => __( 'Could not save. Please try again.', 'easysite-pro' ),
			'unsaved'        => __( 'You have unsaved changes', 'easysite-pro' ),
			'siteSettings'   => __( 'Site colors & logo', 'easysite-pro' ),
			'editLink'       => __( 'Edit link', 'easysite-pro' ),
			'linkUrl'        => __( 'Button link URL', 'easysite-pro' ),
			'desktop'        => __( 'Desktop', 'easysite-pro' ),
			'tablet'         => __( 'Tablet', 'easysite-pro' ),
			'mobile'         => __( 'Mobile', 'easysite-pro' ),
			'editHeader'     => __( 'Edit header', 'easysite-pro' ),
			'editFooter'     => __( 'Edit footer', 'easysite-pro' ),
			'headerLayout'   => __( 'Header layout', 'easysite-pro' ),
			'footerLayout'   => __( 'Footer layout', 'easysite-pro' ),
			'hideOnDevice'   => __( 'Hide on this device', 'easysite-pro' ),
			'bold'           => __( 'Bold', 'easysite-pro' ),
			'italic'         => __( 'Italic', 'easysite-pro' ),
			'underline'      => __( 'Underline', 'easysite-pro' ),
			'link'           => __( 'Link', 'easysite-pro' ),
			'heading'        => __( 'Heading', 'easysite-pro' ),
			'columns'        => __( 'Columns', 'easysite-pro' ),
			'aiWrite'        => __( 'Write for me', 'easysite-pro' ),
			'writing'        => __( 'Writing…', 'easysite-pro' ),
			'aiDone'         => __( 'Text updated!', 'easysite-pro' ),
			'editMenu'       => __( 'Menu', 'easysite-pro' ),
			'editPopup'      => __( 'Popup', 'easysite-pro' ),
			'pageTemplate'   => __( 'Page template', 'easysite-pro' ),
			'templateConfirm'=> __( 'Replace current page content with this template?', 'easysite-pro' ),
			'menuSaved'      => __( 'Menu updated', 'easysite-pro' ),
			'globalSaved'    => __( 'Section saved to library!', 'easysite-pro' ),
			'globalName'     => __( 'Name this section:', 'easysite-pro' ),
			'designCopied'   => __( 'Design copied. Paste on another section.', 'easysite-pro' ),
			'designPasted'   => __( 'Design applied!', 'easysite-pro' ),
			'tourText'       => __( 'Click any text to edit it directly on the page.', 'easysite-pro' ),
			'tourImage'      => __( 'Click images to change them from your media library.', 'easysite-pro' ),
			'tourHeader'     => __( 'Use Header and Footer buttons to edit site-wide areas.', 'easysite-pro' ),
			'tourSave'       => __( 'Click Save when you are done editing.', 'easysite-pro' ),
			'savedSections'  => __( 'Saved sections', 'easysite-pro' ),
			'sectionAdded'   => __( 'Section added!', 'easysite-pro' ),
			'error'          => __( 'Something went wrong.', 'easysite-pro' ),
			'undone'         => __( 'Change restored', 'easysite-pro' ),
			'pageHistory'    => __( 'Page history', 'easysite-pro' ),
			'historyHelp'    => __( 'Restore a previously saved version of this page.', 'easysite-pro' ),
			'noHistory'      => __( 'No saved versions yet. Save the page to create history.', 'easysite-pro' ),
			'restore'        => __( 'Restore', 'easysite-pro' ),
			'restoreConfirm' => __( 'Restore this saved version? Unsaved changes will be lost.', 'easysite-pro' ),
			'revisionRestored'=> __( 'Version restored!', 'easysite-pro' ),
			'sections'       => __( 'sections', 'easysite-pro' ),
			'exportPage'     => __( 'Export page', 'easysite-pro' ),
			'importPage'     => __( 'Import page', 'easysite-pro' ),
			'pageSeo'        => __( 'Page SEO', 'easysite-pro' ),
			'seoTitle'       => __( 'SEO title', 'easysite-pro' ),
			'seoDescription' => __( 'Meta description', 'easysite-pro' ),
			'suggestMeta'    => __( 'Suggest description', 'easysite-pro' ),
			'altText'        => __( 'Suggest alt text', 'easysite-pro' ),
			'presets'        => __( 'Quick presets', 'easysite-pro' ),
			'allSections'    => __( 'All sections', 'easysite-pro' ),
			'formLabels'     => __( 'Form labels', 'easysite-pro' ),
			'bulkAlt'        => __( 'Alt text all images', 'easysite-pro' ),
			'brandColors'    => __( 'Brand colors', 'easysite-pro' ),
			'suggestTitle'   => __( 'Suggest title', 'easysite-pro' ),
			'shorter'        => __( 'Shorter', 'easysite-pro' ),
			'friendlier'     => __( 'Friendlier', 'easysite-pro' ),
			'professional'   => __( 'Professional', 'easysite-pro' ),
			'shortcutsHelp'  => __( 'Ctrl+S save, Ctrl+Z undo, Esc close panel', 'easysite-pro' ),
		),
	) );
}

/**
 * Render editor toolbar and panels in footer.
 */
function easysite_ve_render_shell() {
	?>
	<div id="esb-ve-toolbar" class="esb-ve-toolbar" role="toolbar" aria-label="<?php esc_attr_e( 'Visual editor', 'easysite-pro' ); ?>">
		<div class="esb-ve-toolbar__brand">
			<span class="dashicons dashicons-edit"></span>
			<strong><?php echo esc_html( easysite_get_brand_name() ); ?> <?php esc_html_e( 'Editor', 'easysite-pro' ); ?></strong>
			<span class="esb-ve-status" id="esb-ve-status"></span>
		</div>
		<div class="esb-ve-toolbar__actions">
			<div class="esb-ve-responsive" role="group" aria-label="<?php esc_attr_e( 'Preview device', 'easysite-pro' ); ?>">
				<button type="button" class="esb-ve-btn esb-ve-btn--ghost esb-ve-device is-active" data-device="desktop" title="<?php esc_attr_e( 'Desktop', 'easysite-pro' ); ?>"><span class="dashicons dashicons-desktop"></span></button>
				<button type="button" class="esb-ve-btn esb-ve-btn--ghost esb-ve-device" data-device="tablet" title="<?php esc_attr_e( 'Tablet', 'easysite-pro' ); ?>"><span class="dashicons dashicons-tablet"></span></button>
				<button type="button" class="esb-ve-btn esb-ve-btn--ghost esb-ve-device" data-device="mobile" title="<?php esc_attr_e( 'Mobile', 'easysite-pro' ); ?>"><span class="dashicons dashicons-smartphone"></span></button>
			</div>
			<button type="button" class="esb-ve-btn esb-ve-btn--ghost" id="esb-ve-edit-header">
				<span class="dashicons dashicons-arrow-up-alt"></span>
				<?php esc_html_e( 'Header', 'easysite-pro' ); ?>
			</button>
			<button type="button" class="esb-ve-btn esb-ve-btn--ghost" id="esb-ve-edit-footer">
				<span class="dashicons dashicons-arrow-down-alt"></span>
				<?php esc_html_e( 'Footer', 'easysite-pro' ); ?>
			</button>
			<button type="button" class="esb-ve-btn esb-ve-btn--ghost" id="esb-ve-add-section">
				<span class="dashicons dashicons-plus-alt2"></span>
				<?php esc_html_e( 'Add Section', 'easysite-pro' ); ?>
			</button>
			<a href="<?php echo esc_url( admin_url( 'admin.php?page=easysite-site-settings' ) ); ?>" class="esb-ve-btn esb-ve-btn--ghost" target="_blank">
				<span class="dashicons dashicons-admin-appearance"></span>
				<?php esc_html_e( 'Colors & Logo', 'easysite-pro' ); ?>
			</a>
			<button type="button" class="esb-ve-btn esb-ve-btn--primary" id="esb-ve-save">
				<span class="dashicons dashicons-saved"></span>
				<?php esc_html_e( 'Save', 'easysite-pro' ); ?>
			</button>
			<a href="<?php echo esc_url( remove_query_arg( 'easysite_edit' ) ); ?>" class="esb-ve-btn esb-ve-btn--exit" id="esb-ve-exit">
				<?php esc_html_e( 'Exit', 'easysite-pro' ); ?>
			</a>
		</div>
	</div>

	<div id="esb-ve-library" class="esb-ve-panel esb-ve-panel--library" hidden>
		<div class="esb-ve-panel__head">
			<h3><?php esc_html_e( 'Add a section', 'easysite-pro' ); ?></h3>
			<button type="button" class="esb-ve-panel__close" data-close-panel>&times;</button>
		</div>
		<div class="esb-ve-panel__body" id="esb-ve-library-grid"></div>
	</div>

	<div id="esb-ve-settings" class="esb-ve-panel esb-ve-panel--settings" hidden>
		<div class="esb-ve-panel__head">
			<h3 id="esb-ve-settings-title"><?php esc_html_e( 'Section settings', 'easysite-pro' ); ?></h3>
			<button type="button" class="esb-ve-panel__close" data-close-panel>&times;</button>
		</div>
		<div class="esb-ve-panel__tabs">
			<button type="button" class="esb-ve-tab is-active" data-tab="content"><?php esc_html_e( 'Content', 'easysite-pro' ); ?></button>
			<button type="button" class="esb-ve-tab" data-tab="design"><?php esc_html_e( 'Design', 'easysite-pro' ); ?></button>
			<button type="button" class="esb-ve-tab" data-tab="responsive"><?php esc_html_e( 'Responsive', 'easysite-pro' ); ?></button>
		</div>
		<div class="esb-ve-panel__body">
			<div id="esb-ve-settings-content" class="esb-ve-tab-panel is-active"></div>
			<div id="esb-ve-settings-design" class="esb-ve-tab-panel" hidden></div>
			<div id="esb-ve-settings-responsive" class="esb-ve-tab-panel" hidden>
				<p class="description"><?php esc_html_e( 'Overrides for the currently selected preview device (tablet or mobile).', 'easysite-pro' ); ?></p>
				<div id="esb-ve-responsive-fields"></div>
			</div>
		</div>
	</div>

	<div id="esb-ve-header-panel" class="esb-ve-panel esb-ve-panel--header" hidden>
		<div class="esb-ve-panel__head">
			<h3><?php esc_html_e( 'Edit header', 'easysite-pro' ); ?></h3>
			<button type="button" class="esb-ve-panel__close" data-close-panel>&times;</button>
		</div>
		<div class="esb-ve-panel__body" id="esb-ve-header-fields"></div>
	</div>

	<div id="esb-ve-footer-panel" class="esb-ve-panel esb-ve-panel--footer" hidden>
		<div class="esb-ve-panel__head">
			<h3><?php esc_html_e( 'Edit footer', 'easysite-pro' ); ?></h3>
			<button type="button" class="esb-ve-panel__close" data-close-panel>&times;</button>
		</div>
		<div class="esb-ve-panel__body" id="esb-ve-footer-fields"></div>
	</div>

	<div id="esb-ve-rte-toolbar" class="esb-ve-rte-toolbar" hidden>
		<button type="button" data-cmd="bold" title="<?php esc_attr_e( 'Bold', 'easysite-pro' ); ?>"><strong>B</strong></button>
		<button type="button" data-cmd="italic" title="<?php esc_attr_e( 'Italic', 'easysite-pro' ); ?>"><em>I</em></button>
		<button type="button" data-cmd="underline" title="<?php esc_attr_e( 'Underline', 'easysite-pro' ); ?>"><u>U</u></button>
		<button type="button" data-cmd="createLink" title="<?php esc_attr_e( 'Link', 'easysite-pro' ); ?>"><span class="dashicons dashicons-admin-links"></span></button>
		<button type="button" data-cmd="formatBlock" data-value="h2" title="H2">H2</button>
		<button type="button" data-cmd="formatBlock" data-value="h3" title="H3">H3</button>
		<button type="button" data-cmd="formatBlock" data-value="p" title="P">P</button>
	</div>

	<div id="esb-ve-link-modal" class="esb-ve-modal" hidden>
		<div class="esb-ve-modal__box">
			<h3><?php esc_html_e( 'Edit button link', 'easysite-pro' ); ?></h3>
			<input type="url" id="esb-ve-link-input" class="esb-ve-input" placeholder="/contact" />
			<div class="esb-ve-modal__actions">
				<button type="button" class="esb-ve-btn esb-ve-btn--ghost" data-close-modal><?php esc_html_e( 'Cancel', 'easysite-pro' ); ?></button>
				<button type="button" class="esb-ve-btn esb-ve-btn--primary" id="esb-ve-link-save"><?php esc_html_e( 'Apply', 'easysite-pro' ); ?></button>
			</div>
		</div>
	</div>
	<?php
}

/**
 * Admin bar: Edit visually link.
 *
 * @param WP_Admin_Bar $bar Admin bar.
 */
function easysite_ve_admin_bar( $bar ) {
	if ( ! is_user_logged_in() ) {
		return;
	}

	$post_id = easysite_ve_get_editable_post_id();
	if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
		return;
	}

	if ( easysite_ve_active() ) {
		$bar->add_node( array(
			'id'    => 'easysite-ve-active',
			'title' => '<span style="color:#7c3aed;font-weight:600;">' . esc_html__( 'Editing visually', 'easysite-pro' ) . '</span>',
			'href'  => false,
		) );
		return;
	}

	$url = add_query_arg( 'easysite_edit', '1', get_permalink( $post_id ) );
	$bar->add_node( array(
		'id'    => 'easysite-ve-edit',
		'title' => '<span class="ab-icon dashicons dashicons-edit" style="top:2px;font-size:18px;"></span> ' . esc_html__( 'Edit Page Visually', 'easysite-pro' ),
		'href'  => $url,
		'meta'  => array( 'class' => 'easysite-ve-edit-link' ),
	) );
}
add_action( 'admin_bar_menu', 'easysite_ve_admin_bar', 80 );

/**
 * AJAX: Save layout from visual editor.
 */
function easysite_ajax_ve_save_layout() {
	check_ajax_referer( 'easysite_ve_nonce', 'nonce' );

	$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
	if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied.', 'easysite-pro' ) ) );
	}

	$raw = isset( $_POST['layout'] ) ? wp_unslash( $_POST['layout'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
	$layout = json_decode( $raw, true );
	if ( ! is_array( $layout ) ) {
		wp_send_json_error( array( 'message' => __( 'Invalid layout data.', 'easysite-pro' ) ) );
	}

	$layout = easysite_sanitize_builder_layout( $layout );

	$old_layout = easysite_get_builder_layout( $post_id );
	if ( ! empty( $old_layout ) ) {
		easysite_ve_save_revision( $post_id, $old_layout );
	}

	update_post_meta( $post_id, EASYSITE_BUILDER_ENABLED, '1' );
	update_post_meta( $post_id, EASYSITE_BUILDER_META, wp_json_encode( $layout ) );

	// Save header/footer region data if provided.
	if ( isset( $_POST['regions'] ) ) {
		$regions = json_decode( wp_unslash( $_POST['regions'] ), true ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
		if ( is_array( $regions ) ) {
			easysite_ve_save_regions( $regions );
		}
	}

	wp_send_json_success( array( 'message' => __( 'Saved!', 'easysite-pro' ) ) );
}
add_action( 'wp_ajax_easysite_ve_save_layout', 'easysite_ajax_ve_save_layout' );

/**
 * Save header/footer region settings from visual editor.
 *
 * @param array $regions Region data.
 */
function easysite_ve_save_regions( $regions ) {
	if ( ! current_user_can( 'edit_theme_options' ) ) {
		return;
	}

	if ( ! empty( $regions['header_layout'] ) && is_array( $regions['header_layout'] ) ) {
		$layout = array_map( 'sanitize_key', $regions['header_layout'] );
		set_theme_mod( 'easysite_header_builder_layout', $layout );
	}

	if ( ! empty( $regions['footer_layout'] ) && is_array( $regions['footer_layout'] ) ) {
		$footer = array(
			'columns' => absint( $regions['footer_layout']['columns'] ?? 3 ),
			'blocks'  => array_map( 'sanitize_key', (array) ( $regions['footer_layout']['blocks'] ?? array() ) ),
		);
		set_theme_mod( 'easysite_footer_builder_layout', $footer );
	}

	$mods = array(
		'header_button_text' => 'easysite_header_button_text',
		'header_button_link' => 'easysite_header_button_link',
		'footer_text'        => 'easysite_footer_text',
		'popup_title'        => 'easysite_popup_title',
		'popup_text'         => 'easysite_popup_text',
		'popup_button'       => 'easysite_popup_button_text',
		'form_label_name'    => 'easysite_form_label_name',
		'form_label_email'   => 'easysite_form_label_email',
		'form_label_message' => 'easysite_form_label_message',
		'form_label_submit'  => 'easysite_form_label_submit',
	);

	foreach ( $mods as $key => $mod_key ) {
		if ( isset( $regions[ $key ] ) ) {
			set_theme_mod( $mod_key, sanitize_text_field( $regions[ $key ] ) );
		}
	}

	if ( ! empty( $regions['site_title'] ) ) {
		update_option( 'blogname', sanitize_text_field( $regions['site_title'] ) );
	}

	if ( isset( $regions['logo_id'] ) ) {
		$logo_id = absint( $regions['logo_id'] );
		if ( $logo_id ) {
			set_theme_mod( 'custom_logo', $logo_id );
		} else {
			remove_theme_mod( 'custom_logo' );
		}
	}
}

/**
 * AJAX: Re-render a single section block.
 */
function easysite_ajax_ve_render_block() {
	check_ajax_referer( 'easysite_ve_nonce', 'nonce' );

	$post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0;
	if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
		wp_send_json_error();
	}

	$raw = isset( $_POST['block'] ) ? wp_unslash( $_POST['block'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
	$block = json_decode( $raw, true );
	if ( ! is_array( $block ) || empty( $block['type'] ) ) {
		wp_send_json_error();
	}

	$GLOBALS['easysite_ve_active'] = true;
	$html = easysite_ve_render_block_html( $block, 0 );
	wp_send_json_success( array( 'html' => $html ) );
}
add_action( 'wp_ajax_easysite_ve_render_block', 'easysite_ajax_ve_render_block' );

/**
 * Render one block HTML for AJAX / visual editor.
 *
 * @param array $block   Block data.
 * @param int   $index   Block index.
 * @return string
 */
function easysite_ve_render_block_html( $block, $index = 0 ) {
	$type = $block['type'] ?? '';
	$data = $block['fields'] ?? array();
	$fn   = 'easysite_pb_render_' . str_replace( '-', '_', $type );

	if ( ! function_exists( $fn ) ) {
		return '';
	}

	$GLOBALS['easysite_pb_current_block'] = $block;

	$animate = easysite_get_mod( 'easysite_animations', true );
	$classes = 'easysite-pb-block easysite-pb-' . sanitize_html_class( $type ) . ' esb-ve-block';
	if ( $animate ) {
		$classes .= ' easysite-animate';
	}

	ob_start();
	echo '<div class="' . esc_attr( $classes ) . '"';
	echo ' data-block-id="' . esc_attr( $block['id'] ?? '' ) . '"';
	echo ' data-block-index="' . esc_attr( (string) $index ) . '"';
	echo ' data-block-type="' . esc_attr( $type ) . '"';
	echo easysite_block_design_attrs( $block ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	echo '>';
	call_user_func( $fn, $data );
	echo '</div>';
	return ob_get_clean();
}
