<?php
/**
 * Code Snippet - Add/Edit Page
 *
 * Full-page snippet editor (PowerSuite admin layout).
 *
 * @package CodeSnippet
 * @since 1.0.0
 */

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

$snippet_data = $snippet_data ?? null;
$is_edit      = $is_edit ?? false;
$d            = $snippet_data ?: [
	'id'                   => 0,
	'title'                => '',
	'code'                 => '',
	'code_type'            => 'html',
	'location'             => 'footer',
	'location_param'       => 1,
	'location_selector'    => '',
	'location_element_index' => '',
	'custom_shortcode'     => '',
	'auto_insert'          => true,
	'priority'             => 10,
	'active'               => true,
	'schedule_enabled'     => false,
	'schedule_start'       => '',
	'schedule_end'         => '',
	'device_type'          => 'all',
	'conditional_enabled'   => false,
	'conditional_show'     => '1',
	'revisions_enabled'     => false,
	'conditional_rules'    => [],
	'load_as_file'         => false,
];

$list_url  = admin_url( 'admin.php?page=powersuite-code-snippet' );
$ajax_url  = admin_url( 'admin-ajax.php' );
$nonce     = wp_create_nonce( 'wpps_cs_nonce' );

$locations_ui       = \CodeSnippet\Module::getLocationsForUI();
$location_labels    = \CodeSnippet\Module::getLocations();
$php_only_locations = \CodeSnippet\Module::getPhpOnlyLocations();
$woo_locations      = \CodeSnippet\Module::getWooLocations();
$woo_installed      = class_exists( 'WooCommerce' );
$cs_settings_url    = admin_url( 'admin.php?page=powersuite-code-snippet&view=settings' );
$merge_fe_ui        = (bool) \CodeSnippet\Module::getSetting( 'merge_frontend_only_php', false );
$is_pro = $is_pro ?? \CodeSnippet\Module::isProLicensed();
$license_page_url = function_exists( 'wp_powersuite_premium_upsell_url' )
	? wp_powersuite_premium_upsell_url()
	: ( defined( 'WP_POWERSUITE_PRODUCT_URL' ) ? WP_POWERSUITE_PRODUCT_URL : 'https://wppowersuite.com/' );
$upsell_label = ( function_exists( 'wp_powersuite_can_activate_license' ) && wp_powersuite_can_activate_license() )
	? __( 'Activate license', 'wp-powersuite' )
	: __( 'Get WP PowerSuite Pro', 'wp-powersuite' );
$upsell_attrs = ( function_exists( 'wp_powersuite_can_activate_license' ) && wp_powersuite_can_activate_license() )
	? ''
	: ' target="_blank" rel="noopener noreferrer"';

$code_types = [
	'html' => [
		'label' => __( 'HTML Snippet', 'wp-powersuite' ),
		'desc'  => __( 'Easily insert scripts from other sites or build custom elements using HTML.', 'wp-powersuite' ),
		'is_pro' => false,
	],
	'css' => [
		'label' => __( 'CSS Snippet', 'wp-powersuite' ),
		'desc'  => __( 'Write CSS styles directly and easily customize how your website looks.', 'wp-powersuite' ),
		'is_pro' => false,
	],
	'js' => [
		'label' => __( 'JavaScript Snippet', 'wp-powersuite' ),
		'desc'  => __( 'Add custom JavaScript code to your site to add interactivity or integrate with other services.', 'wp-powersuite' ),
		'is_pro' => true,
	],
	'php' => [
		'label' => __( 'PHP Snippet', 'wp-powersuite' ),
		'desc'  => __( 'Extend or add functionality using PHP code with full control on where it\'s executed.', 'wp-powersuite' ),
		'is_pro' => true,
	],
];

$initial_code   = $d['code'];
$php_prefix     = '<' . '?php' . "\n";
$js_open_tag    = '<script>';
$js_close_tag   = '</script>';
if ( empty( trim( $initial_code ) ) ) {
	if ( $d['code_type'] === 'js' ) {
		$initial_code = "<script>\n\n</script>";
	} elseif ( $d['code_type'] === 'php' ) {
		$initial_code = $php_prefix;
	}
} elseif ( $d['code_type'] === 'php' && strpos( ltrim( $initial_code ), '<?php' ) !== 0 ) {
	$initial_code = $php_prefix . $initial_code;
} elseif ( $d['code_type'] === 'js' ) {
	$trimmed = ltrim( $initial_code );
	if ( strpos( $trimmed, $js_open_tag ) !== 0 ) {
		$initial_code = $js_open_tag . "\n" . $initial_code;
	}
	if ( substr( rtrim( $initial_code ), -strlen( $js_close_tag ) ) !== $js_close_tag ) {
		$initial_code = $initial_code . ( $initial_code ? "\n" : '' ) . $js_close_tag;
	}
}
$editor_height = max( 100, min( 800, (int) \CodeSnippet\Module::getSetting( 'editor_height', 300 ) ) );
$editor_auto   = (bool) \CodeSnippet\Module::getSetting( 'editor_height_auto', false );
?>
<div class="wrap wpps-cs-wrap wpps-cs-edit-wrap<?php echo $editor_auto ? ' wpps-cs-editor-auto' : ''; ?>" data-editor-height="<?php echo esc_attr( (string) $editor_height ); ?>" data-editor-auto="<?php echo $editor_auto ? '1' : '0'; ?>">
	<?php if ( $editor_auto ) : ?>
	<style>.wpps-cs-editor-auto .wpps-cs-code-panel .wpps-cs-code-wrap,.wpps-cs-editor-auto .wpps-cs-code-panel .wpps-cs-code-editor,.wpps-cs-editor-auto .wpps-cs-code-panel .CodeMirror,.wpps-cs-editor-auto .wpps-cs-code-panel .CodeMirror-scroll{height:auto!important;min-height:200px;}</style>
	<?php else : ?>
	<style>.wpps-cs-code-panel{--cs-editor-height:<?php echo esc_html( (string) $editor_height ); ?>px;}.wpps-cs-code-panel .wpps-cs-code-wrap,.wpps-cs-code-panel .wpps-cs-code-editor,.wpps-cs-code-panel .CodeMirror,.wpps-cs-code-panel .CodeMirror-scroll{min-height:var(--cs-editor-height);height:var(--cs-editor-height);}</style>
	<?php endif; ?>
	<hr class="wp-header-end">
	<a href="<?php echo esc_url( $list_url ); ?>" class="wpps-cs-back">&larr; <?php esc_html_e( 'Back to Snippets', 'wp-powersuite' ); ?></a>

	<div class="wpps-cs-edit-header">
		<h1 class="wpps-cs-edit-title"><?php echo $is_edit ? esc_html__( 'Edit Snippet', 'wp-powersuite' ) : esc_html__( 'Create Custom Snippet', 'wp-powersuite' ); ?></h1>
		<div class="wpps-cs-edit-header-actions">
			<label class="wpps-cs-active-toggle">
				<span class="wpps-cs-active-label"><?php echo $d['active'] ? esc_html__( 'Active', 'wp-powersuite' ) : esc_html__( 'Inactive', 'wp-powersuite' ); ?></span>
				<input type="checkbox" id="wpps-cs-active" value="1" <?php checked( $d['active'] ); ?>>
				<span class="wpps-cs-toggle-slider"></span>
			</label>
			<button type="submit" form="wpps-cs-edit-form" id="wpps-cs-save-btn" class="wpps-cs-btn wpps-cs-btn-primary">
				<?php esc_html_e( 'Save Snippet', 'wp-powersuite' ); ?>
			</button>
		</div>
	</div>

	<?php
	$module_enabled = \WP_PowerSuite\Core\OptionStoreModuleSettingsRepository::isModuleEnabled( 'code-snippet' );
	$auto_deactivated = $is_edit && $d['id'] > 0 ? get_post_meta( $d['id'], '_wpps_auto_deactivated', true ) : '';
	$auto_deactivated_error = $auto_deactivated ? get_post_meta( $d['id'], '_wpps_auto_deactivated_error', true ) : '';
	$last_php_err_raw       = $is_edit && $d['id'] > 0 ? get_post_meta( $d['id'], '_wpps_last_php_error', true ) : '';
	$last_php_err           = is_string( $last_php_err_raw ) ? json_decode( $last_php_err_raw, true ) : null;
	$has_static_notices     = ! $module_enabled
		|| ( $auto_deactivated && $auto_deactivated_error )
		|| ( $is_edit && $d['id'] > 0 && is_array( $last_php_err ) && ! empty( $last_php_err['message'] ) && ! ( $auto_deactivated && $auto_deactivated_error ) )
		|| ( $is_edit && isset( $_GET['restored'] ) && sanitize_key( wp_unslash( $_GET['restored'] ) ) === '1' );
	?>
	<?php if ( $has_static_notices ) : ?>
	<div class="wpps-cs-edit-notices">
	<?php if ( ! $module_enabled ) : ?>
		<div class="notice notice-warning">
			<p>
				<strong><?php esc_html_e( 'Code Snippet module is disabled.', 'wp-powersuite' ); ?></strong>
				<?php esc_html_e( 'Snippets will not run until you enable this module in PowerSuite settings.', 'wp-powersuite' ); ?>
				<a href="<?php echo esc_url( admin_url( 'admin.php?page=powersuite' ) ); ?>"><?php esc_html_e( 'Enable module', 'wp-powersuite' ); ?></a>
			</p>
		</div>
	<?php endif; ?>
	<?php if ( $auto_deactivated && $auto_deactivated_error ) : ?>
		<div class="notice notice-error">
			<p>
				<strong><?php esc_html_e( 'This snippet was automatically deactivated due to a PHP error.', 'wp-powersuite' ); ?></strong>
				<?php echo esc_html( $auto_deactivated_error ); ?>
				<?php esc_html_e( 'Fix the error and reactivate the snippet.', 'wp-powersuite' ); ?>
				<a href="<?php echo esc_url( admin_url( 'admin.php?page=powersuite-code-snippet&view=logs' ) ); ?>"><?php esc_html_e( 'View error logs', 'wp-powersuite' ); ?></a>
			</p>
		</div>
	<?php endif; ?>
	<?php if ( $is_edit && $d['id'] > 0 && is_array( $last_php_err ) && ! empty( $last_php_err['message'] ) && ! ( $auto_deactivated && $auto_deactivated_error ) ) : ?>
		<div class="notice notice-warning">
			<p>
				<strong><?php esc_html_e( 'Last PHP error (this snippet):', 'wp-powersuite' ); ?></strong>
				<?php echo esc_html( (string) $last_php_err['message'] ); ?>
				<?php if ( ! empty( $last_php_err['time'] ) ) : ?>
					<span class="description">(<?php echo esc_html( (string) $last_php_err['time'] ); ?>)</span>
				<?php endif; ?>
				<a href="<?php echo esc_url( admin_url( 'admin.php?page=powersuite-code-snippet&view=logs' ) ); ?>"><?php esc_html_e( 'Logs', 'wp-powersuite' ); ?></a>
			</p>
		</div>
	<?php endif; ?>
	<?php if ( $is_edit && isset( $_GET['restored'] ) && sanitize_key( wp_unslash( $_GET['restored'] ) ) === '1' ) : ?>
		<div class="notice notice-success is-dismissible"><p><?php esc_html_e( 'Revision restored successfully.', 'wp-powersuite' ); ?></p></div>
	<?php endif; ?>
	</div>
	<?php endif; ?>

	<div id="wpps-cs-edit-notice" class="notice wpps-cs-inline-notice" hidden>
		<p id="wpps-cs-edit-notice-message"></p>
	</div>

	<!-- Fixed toast for copy/save feedback - always visible in viewport -->
	<div id="wpps-cs-toast" class="wpps-cs-toast" role="status" aria-live="polite" aria-atomic="true" aria-hidden="true">
		<span id="wpps-cs-toast-message"></span>
	</div>

	<form id="wpps-cs-edit-form" class="wpps-cs-edit-form">
		<input type="hidden" id="wpps-cs-id" value="<?php echo (int) $d['id']; ?>">
		<input type="hidden" id="wpps-cs-nonce" value="<?php echo esc_attr( $nonce ); ?>">

		<div class="wpps-cs-edit-stack">
		<!-- Title -->
		<div class="wpps-cs-edit-panel wpps-cs-title-panel">
			<input type="text" id="wpps-cs-title" class="wpps-cs-title-input" value="<?php echo esc_attr( $d['title'] ); ?>" placeholder="<?php esc_attr_e( 'Add title for snippet', 'wp-powersuite' ); ?>" required>
		</div>

		<!-- Code Preview -->
		<div class="wpps-cs-edit-panel wpps-cs-code-panel">
			<div class="wpps-cs-code-panel-header">
				<div class="wpps-cs-code-panel-title-row">
					<span class="dashicons dashicons-editor-code wpps-cs-code-panel-icon"></span>
					<h2 class="wpps-cs-panel-title"><?php esc_html_e( 'Code Preview', 'wp-powersuite' ); ?></h2>
				</div>
				<div class="wpps-cs-code-panel-tools">
					<button type="button" id="wpps-cs-theme-toggle" class="wpps-cs-editor-tool-btn" aria-pressed="false" title="<?php esc_attr_e( 'Toggle editor dark mode', 'wp-powersuite' ); ?>">
						<span class="wpps-cs-theme-icon" aria-hidden="true">
							<svg class="wpps-cs-ico wpps-cs-ico-moon" viewBox="0 0 24 24" width="15" height="15"><path fill="currentColor" d="M12.3 2.6a9.5 9.5 0 1 0 9.1 12.2 7.6 7.6 0 0 1-9.5-9.5c0-.93.17-1.83.4-2.7z"/></svg>
							<svg class="wpps-cs-ico wpps-cs-ico-sun" viewBox="0 0 24 24" width="15" height="15" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="4.2"/><path d="M12 2.5v2.2M12 19.3v2.2M4.4 4.4l1.6 1.6M18 18l1.6 1.6M2.5 12h2.2M19.3 12h2.2M4.4 19.6l1.6-1.6M18 6l1.6-1.6"/></svg>
						</span>
						<span class="wpps-cs-theme-toggle-label"><?php esc_html_e( 'Dark', 'wp-powersuite' ); ?></span>
					</button>
					<div class="wpps-cs-code-type-wrap">
						<label class="wpps-cs-code-type-label"><?php esc_html_e( 'Code Type', 'wp-powersuite' ); ?></label>
						<button type="button" id="wpps-cs-code-type-trigger" class="wpps-cs-code-type-trigger" aria-haspopup="dialog" aria-expanded="false">
							<span id="wpps-cs-code-type-display"><?php echo esc_html( $code_types[ $d['code_type'] ]['label'] ?? $code_types['html']['label'] ); ?></span>
							<span class="dashicons dashicons-arrow-down-alt2"></span>
						</button>
						<input type="hidden" id="wpps-cs-code-type" value="<?php echo esc_attr( $d['code_type'] ); ?>">
					</div>
				</div>
			</div>
			<div class="wpps-cs-code-wrap">
				<textarea id="wpps-cs-code" class="wpps-cs-code-editor" placeholder="<?php esc_attr_e( 'Enter your code here...', 'wp-powersuite' ); ?>"><?php echo esc_textarea( $initial_code ); ?></textarea>
			</div>
			<div class="wpps-cs-code-statusbar" aria-hidden="true">
				<span class="wpps-cs-status-left">
					<span id="wpps-cs-status-lang" class="wpps-cs-status-item wpps-cs-status-lang"><?php echo esc_html( strtoupper( $d['code_type'] ) ); ?></span>
				</span>
				<span class="wpps-cs-status-right">
					<span id="wpps-cs-status-spaces" class="wpps-cs-status-item"><?php esc_html_e( 'Spaces: 4', 'wp-powersuite' ); ?></span>
					<span id="wpps-cs-status-pos" class="wpps-cs-status-item">Ln 1, Col 1</span>
				</span>
			</div>
		</div>


		<!-- Accordions -->
		<div class="wpps-cs-accordions">
			<!-- 1. Insertion -->
			<div class="wpps-cs-accordion is-open" data-accordion-id="insertion">
				<button type="button" class="wpps-cs-accordion-header" aria-expanded="true" aria-controls="wpps-cs-accordion-insertion">
					<span class="wpps-cs-accordion-title">
						<?php esc_html_e( 'Insertion', 'wp-powersuite' ); ?>
						<span class="wpps-cs-accordion-tooltip" aria-label="<?php esc_attr_e( 'Help', 'wp-powersuite' ); ?>"><span class="wpps-cs-accordion-tooltip-trigger">?</span><span class="wpps-cs-accordion-tooltip-panel"><?php esc_html_e( 'Your snippet can be either automatically executed or only used as a shortcode. When using the "Auto Insert" option you can choose the location where your snippet will be placed automatically.', 'wp-powersuite' ); ?></span></span>
					</span>
					<span class="dashicons dashicons-arrow-down-alt2 wpps-cs-accordion-chevron"></span>
				</button>
				<div id="wpps-cs-accordion-insertion" class="wpps-cs-accordion-body">
					<p class="wpps-cs-insertion-desc"><?php esc_html_e( 'Choose "Auto Insert" if you want the snippet to be automatically executed in one of the locations available. In "Shortcode" mode, the snippet will only be executed where the shortcode is inserted.', 'wp-powersuite' ); ?></p>
					<div class="wpps-cs-insert-method">
						<label class="wpps-cs-insert-method-label"><?php esc_html_e( 'Insert Method', 'wp-powersuite' ); ?></label>
						<div class="wpps-cs-insert-method-btns">
							<label class="wpps-cs-insert-btn <?php echo $d['auto_insert'] ? 'is-active' : ''; ?>">
								<input type="radio" name="insert_method" value="auto" <?php checked( $d['auto_insert'] ); ?>>
								<span class="dashicons dashicons-visibility"></span>
								<?php esc_html_e( 'Auto Insert', 'wp-powersuite' ); ?>
							</label>
							<label class="wpps-cs-insert-btn <?php echo ! $d['auto_insert'] ? 'is-active' : ''; ?>">
								<input type="radio" name="insert_method" value="shortcode" <?php checked( ! $d['auto_insert'] ); ?>>
								<span class="dashicons dashicons-editor-code"></span>
								<?php esc_html_e( 'Shortcode', 'wp-powersuite' ); ?>
							</label>
						</div>
					</div>
					<div id="wpps-cs-location-wrap" class="wpps-cs-location-wrap" style="<?php echo $d['auto_insert'] ? '' : 'display:none;'; ?>">
						<div class="wpps-cs-location-picker-wrap">
							<label class="wpps-cs-location-label"><?php esc_html_e( 'Location', 'wp-powersuite' ); ?></label>
							<div class="wpps-cs-location-picker">
								<button type="button" id="wpps-cs-location-trigger" class="wpps-cs-location-trigger" aria-haspopup="dialog" aria-expanded="false">
									<span id="wpps-cs-location-display"><?php echo esc_html( $location_labels[ $d['location'] ] ?? $d['location'] ); ?></span>
									<span class="dashicons dashicons-arrow-down-alt2"></span>
								</button>
								<input type="hidden" id="wpps-cs-location" value="<?php echo esc_attr( $d['location'] ); ?>">
							</div>
						</div>
						<div id="wpps-cs-location-param-wrap" class="wpps-cs-location-param-wrap" style="<?php echo in_array( $d['location'], [ 'before_paragraph', 'after_paragraph', 'before_post', 'after_post' ], true ) ? '' : 'display:none;'; ?>">
							<label for="wpps-cs-location-param"><?php esc_html_e( 'Position', 'wp-powersuite' ); ?></label>
							<input type="number" id="wpps-cs-location-param" class="wpps-cs-input wpps-cs-input-sm" value="<?php echo (int) ( $d['location_param'] ?? 1 ); ?>" data-wpps-min="1" data-wpps-max="999" data-wpps-step="1">
							<span class="wpps-cs-help" id="wpps-cs-location-param-help"><?php esc_html_e( 'Paragraph number', 'wp-powersuite' ); ?></span>
						</div>
						<div id="wpps-cs-location-selector-wrap" class="wpps-cs-location-selector-wrap" style="<?php echo in_array( $d['location'], [ 'before_element', 'after_element', 'start_element', 'end_element' ], true ) ? '' : 'display:none;'; ?>">
							<label for="wpps-cs-location-selector"><?php esc_html_e( 'CSS Selector', 'wp-powersuite' ); ?></label>
							<input type="text" id="wpps-cs-location-selector" class="wpps-cs-input" value="<?php echo esc_attr( $d['location_selector'] ?? '' ); ?>" placeholder="<?php esc_attr_e( 'e.g. #main, .entry-content, article', 'wp-powersuite' ); ?>">
							<span class="wpps-cs-help"><?php esc_html_e( 'Target HTML element using CSS selector (e.g. #main, .content, header)', 'wp-powersuite' ); ?></span>
							<label for="wpps-cs-location-element-index" class="wpps-cs-element-index-label"><?php esc_html_e( 'Element index (0 = first, leave empty for all)', 'wp-powersuite' ); ?></label>
							<input type="number" id="wpps-cs-location-element-index" class="wpps-cs-input wpps-cs-input-sm" value="<?php echo esc_attr( $d['location_element_index'] ?? '' ); ?>" data-wpps-min="0" data-wpps-max="9999" data-wpps-step="1" placeholder="<?php esc_attr_e( 'All', 'wp-powersuite' ); ?>">
						</div>
						<div id="wpps-cs-frontend-only-php-hint" class="wpps-cs-fe-php-hint" style="display:none;" role="note"></div>
					</div>
					<div id="wpps-cs-shortcode-wrap" class="wpps-cs-shortcode-wrap" style="<?php echo $d['auto_insert'] ? 'display:none;' : ''; ?>">
						<div class="wpps-cs-shortcode-display-wrap">
							<label class="wpps-cs-location-label"><?php esc_html_e( 'Shortcode', 'wp-powersuite' ); ?></label>
							<div class="wpps-cs-shortcode-copy-row">
								<input type="text" id="wpps-cs-shortcode-display" class="wpps-cs-input wpps-cs-shortcode-input" value="<?php echo $d['id'] > 0 ? esc_attr( \CodeSnippet\Module::getShortcodeForSnippet( $d['id'], $d['custom_shortcode'] ?? '' ) ) : esc_attr__( 'Please save the snippet first', 'wp-powersuite' ); ?>" readonly>
								<button type="button" class="wpps-cs-btn wpps-cs-copy-btn" id="wpps-cs-shortcode-copy" title="<?php esc_attr_e( 'Copy', 'wp-powersuite' ); ?>"><?php esc_html_e( 'Copy', 'wp-powersuite' ); ?></button>
							</div>
						</div>
						<div class="wpps-cs-form-group wpps-cs-custom-shortcode-wrap">
							<label for="wpps-cs-custom-shortcode"><?php esc_html_e( 'Custom Shortcode', 'wp-powersuite' ); ?></label>
							<div class="wpps-cs-shortcode-copy-row">
								<input type="text" id="wpps-cs-custom-shortcode" class="wpps-cs-input wpps-cs-shortcode-input" value="<?php echo esc_attr( $d['custom_shortcode'] ?? '' ); ?>" placeholder="<?php esc_attr_e( 'e.g. my_snippet', 'wp-powersuite' ); ?>">
								<button type="button" class="wpps-cs-btn wpps-cs-copy-btn" id="wpps-cs-custom-shortcode-copy" title="<?php esc_attr_e( 'Copy', 'wp-powersuite' ); ?>"><?php esc_html_e( 'Copy', 'wp-powersuite' ); ?></button>
							</div>
							<span class="wpps-cs-help"><?php esc_html_e( 'Use a custom shortcode name instead of the id-based one. Use lowercase letters, numbers, and underscores only.', 'wp-powersuite' ); ?></span>
						</div>
					</div>
					<div class="wpps-cs-schedule-wrap">
						<label class="wpps-cs-schedule-label">
							<input type="checkbox" id="wpps-cs-schedule-enabled" value="1" <?php checked( ! empty( $d['schedule_enabled'] ) ); ?>>
							<?php esc_html_e( 'Schedule snippet', 'wp-powersuite' ); ?>
						</label>
						<span class="wpps-cs-help"><?php esc_html_e( 'Control when this snippet is active by setting start and end dates. Leave empty for no limit. Uses your site\'s timezone.', 'wp-powersuite' ); ?></span>
						<div id="wpps-cs-schedule-fields" class="wpps-cs-schedule-fields" style="<?php echo ! empty( $d['schedule_enabled'] ) ? '' : 'display:none;'; ?>">
							<div class="wpps-cs-schedule-row">
								<div class="wpps-cs-form-group">
									<label for="wpps-cs-schedule-start"><?php esc_html_e( 'Start', 'wp-powersuite' ); ?></label>
									<input type="datetime-local" id="wpps-cs-schedule-start" class="wpps-cs-input" value="<?php echo esc_attr( $d['schedule_start'] ?? '' ); ?>">
								</div>
								<div class="wpps-cs-form-group">
									<label for="wpps-cs-schedule-end"><?php esc_html_e( 'End', 'wp-powersuite' ); ?></label>
									<input type="datetime-local" id="wpps-cs-schedule-end" class="wpps-cs-input" value="<?php echo esc_attr( $d['schedule_end'] ?? '' ); ?>">
								</div>
							</div>
						</div>
					</div>
					<div class="wpps-cs-load-file-wrap">
						<label class="wpps-cs-schedule-label">
							<input type="checkbox" id="wpps-cs-load-as-file" value="1" <?php checked( ! empty( $d['load_as_file'] ) ); ?>>
							<?php esc_html_e( 'Load this snippet from a file', 'wp-powersuite' ); ?>
							</label>
						<span class="wpps-cs-help"><?php esc_html_e( 'Serve this snippet from disk instead of the database. Works alone or with the global Load as Files setting.', 'wp-powersuite' ); ?></span>
					</div>
				</div>
			</div>

			<!-- 2. Device Type -->
			<div class="wpps-cs-accordion <?php echo ! $is_pro ? 'wpps-cs-accordion-pro' : ''; ?>" data-accordion-id="device">
				<button type="button" class="wpps-cs-accordion-header" aria-expanded="false" aria-controls="wpps-cs-accordion-device">
					<span class="wpps-cs-accordion-title">
						<?php esc_html_e( 'Device Type', 'wp-powersuite' ); ?><?php if ( ! $is_pro && function_exists( 'wpps_render_premium_badge' ) ) { wpps_render_premium_badge(); } ?>
						<span class="wpps-cs-accordion-tooltip" aria-label="<?php esc_attr_e( 'Help', 'wp-powersuite' ); ?>"><span class="wpps-cs-accordion-tooltip-trigger">?</span><span class="wpps-cs-accordion-tooltip-panel"><?php esc_html_e( 'Restrict snippet to specific device types (desktop, mobile, tablet).', 'wp-powersuite' ); ?></span></span>
					</span>
					<span class="dashicons dashicons-arrow-down-alt2 wpps-cs-accordion-chevron"></span>
				</button>
				<div id="wpps-cs-accordion-device" class="wpps-cs-accordion-body">
					<?php if ( ! $is_pro ) : ?>
						<div class="wpps-cs-pro-overlay">
							<span class="dashicons dashicons-lock"></span>
							<p><?php esc_html_e( 'Device Type is a PRO feature.', 'wp-powersuite' ); ?></p>
							<a href="<?php echo esc_url( $license_page_url ); ?>" class="wpps-cs-btn wpps-cs-btn-primary"<?php echo $upsell_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static attribute string. ?>><?php echo esc_html( $upsell_label ); ?></a>
						</div>
					<?php endif; ?>
					<label class="wpps-cs-device-label"><?php esc_html_e( 'Load snippet on', 'wp-powersuite' ); ?></label>
					<div class="wpps-cs-device-boxes">
						<label class="wpps-cs-device-box <?php echo ( $d['device_type'] ?? 'all' ) === 'all' ? 'is-selected' : ''; ?>">
							<input type="radio" name="device_type" value="all" <?php checked( ( $d['device_type'] ?? 'all' ), 'all' ); ?> <?php disabled( ! $is_pro ); ?>>
							<span class="wpps-cs-device-box-icon dashicons dashicons-visibility"></span>
							<span class="wpps-cs-device-box-label"><?php esc_html_e( 'All devices', 'wp-powersuite' ); ?></span>
						</label>
						<label class="wpps-cs-device-box <?php echo ( $d['device_type'] ?? 'all' ) === 'desktop' ? 'is-selected' : ''; ?>">
							<input type="radio" name="device_type" value="desktop" <?php checked( ( $d['device_type'] ?? 'all' ), 'desktop' ); ?> <?php disabled( ! $is_pro ); ?>>
							<span class="wpps-cs-device-box-icon dashicons dashicons-desktop"></span>
							<span class="wpps-cs-device-box-label"><?php esc_html_e( 'Desktop', 'wp-powersuite' ); ?></span>
						</label>
						<label class="wpps-cs-device-box <?php echo ( $d['device_type'] ?? 'all' ) === 'mobile' ? 'is-selected' : ''; ?>">
							<input type="radio" name="device_type" value="mobile" <?php checked( ( $d['device_type'] ?? 'all' ), 'mobile' ); ?> <?php disabled( ! $is_pro ); ?>>
							<span class="wpps-cs-device-box-icon dashicons dashicons-smartphone"></span>
							<span class="wpps-cs-device-box-label"><?php esc_html_e( 'Mobile', 'wp-powersuite' ); ?></span>
						</label>
						<label class="wpps-cs-device-box <?php echo ( $d['device_type'] ?? 'all' ) === 'tablet' ? 'is-selected' : ''; ?>">
							<input type="radio" name="device_type" value="tablet" <?php checked( ( $d['device_type'] ?? 'all' ), 'tablet' ); ?> <?php disabled( ! $is_pro ); ?>>
							<span class="wpps-cs-device-box-icon dashicons dashicons-tablet"></span>
							<span class="wpps-cs-device-box-label"><?php esc_html_e( 'Tablet', 'wp-powersuite' ); ?></span>
						</label>
					</div>
					<span class="wpps-cs-help"><?php esc_html_e( 'Restrict snippet to specific device types.', 'wp-powersuite' ); ?></span>
				</div>
			</div>

			<!-- 3. Smart Conditional Logic -->
			<div class="wpps-cs-accordion <?php echo ! $is_pro ? 'wpps-cs-accordion-pro' : ''; ?>" data-accordion-id="conditional">
				<button type="button" class="wpps-cs-accordion-header" aria-expanded="false" aria-controls="wpps-cs-accordion-conditional">
					<span class="wpps-cs-accordion-title">
						<?php esc_html_e( 'Smart Conditional Logic', 'wp-powersuite' ); ?><?php if ( ! $is_pro && function_exists( 'wpps_render_premium_badge' ) ) { wpps_render_premium_badge(); } ?>
						<span class="wpps-cs-accordion-tooltip" aria-label="<?php esc_attr_e( 'Help', 'wp-powersuite' ); ?>"><span class="wpps-cs-accordion-tooltip-trigger">?</span><span class="wpps-cs-accordion-tooltip-panel"><?php esc_html_e( 'Define when this snippet runs based on URL, user role, and more.', 'wp-powersuite' ); ?></span></span>
					</span>
					<span class="dashicons dashicons-arrow-down-alt2 wpps-cs-accordion-chevron"></span>
				</button>
				<div id="wpps-cs-accordion-conditional" class="wpps-cs-accordion-body">
					<?php if ( ! $is_pro ) : ?>
						<div class="wpps-cs-pro-overlay">
							<span class="dashicons dashicons-lock"></span>
							<p><?php esc_html_e( 'Smart Conditional Logic is a PRO feature.', 'wp-powersuite' ); ?></p>
							<a href="<?php echo esc_url( $license_page_url ); ?>" class="wpps-cs-btn wpps-cs-btn-primary"<?php echo $upsell_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static attribute string. ?>><?php echo esc_html( $upsell_label ); ?></a>
						</div>
					<?php endif; ?>
					<label class="wpps-cs-conditional-toggle">
						<input type="checkbox" id="wpps-cs-conditional-enabled" value="1" <?php checked( ! empty( $d['conditional_enabled'] ) ); ?> <?php disabled( ! $is_pro ); ?>>
						<?php esc_html_e( 'Enable conditional logic', 'wp-powersuite' ); ?>
					</label>
					<div id="wpps-cs-conditional-rules-wrap" style="<?php echo ! empty( $d['conditional_enabled'] ) ? '' : 'display:none;'; ?>">
						<label for="wpps-cs-conditional-show"><?php esc_html_e( 'Show snippet when', 'wp-powersuite' ); ?></label>
						<select id="wpps-cs-conditional-show">
							<option value="1" <?php selected( ( $d['conditional_show'] ?? '1' ), '1' ); ?>><?php esc_html_e( 'rules match', 'wp-powersuite' ); ?></option>
							<option value="0" <?php selected( ( $d['conditional_show'] ?? '1' ), '0' ); ?>><?php esc_html_e( 'rules do NOT match', 'wp-powersuite' ); ?></option>
						</select>
						<span class="wpps-cs-help wpps-cs-help-block"><?php esc_html_e( 'Rules in a group are AND. Add a rule group for OR logic.', 'wp-powersuite' ); ?></span>
						<?php
						$rules_data = $d['conditional_rules'] ?? [];
						$groups = isset( $rules_data['groups'] ) && is_array( $rules_data['groups'] ) ? $rules_data['groups'] : ( ! empty( $rules_data ) && isset( $rules_data[0]['type'] ) ? [ $rules_data ] : [ [ [ 'type' => 'url', 'operator' => 'contains', 'value' => '' ] ] ] );
						$page_types = [
							'is_front_page' => __( 'Homepage', 'wp-powersuite' ),
							'is_home'       => __( 'Blog home', 'wp-powersuite' ),
							'is_page'       => __( 'Static page', 'wp-powersuite' ),
							'is_single'     => __( 'Single post', 'wp-powersuite' ),
							'is_archive'    => __( 'Archive', 'wp-powersuite' ),
							'is_search'     => __( 'Search page', 'wp-powersuite' ),
							'is_404'        => __( '404 page', 'wp-powersuite' ),
							'is_author'     => __( 'Author page', 'wp-powersuite' ),
						];
						$post_types = [];
						foreach ( get_post_types( [ 'public' => true ], 'objects' ) as $pt ) {
							$post_types[ $pt->name ] = $pt->label;
						}
						$user_roles = wp_roles()->get_names();
						?>
						<div id="wpps-cs-conditional-groups">
							<?php foreach ( $groups as $gi => $group ) : ?>
							<div class="wpps-cs-conditional-group" data-group-index="<?php echo (int) $gi; ?>">
								<span class="wpps-cs-group-label"><?php echo $gi > 0 ? esc_html__( 'OR', 'wp-powersuite' ) : esc_html__( 'Group', 'wp-powersuite' ); ?></span>
								<div class="wpps-cs-conditional-rules">
									<?php
									$group_rules = is_array( $group ) ? $group : [];
									if ( empty( $group_rules ) ) {
										$group_rules = [ [ 'type' => 'url', 'operator' => 'contains', 'value' => '' ] ];
									}
									foreach ( $group_rules as $ri => $rule ) :
										$r = wp_parse_args( is_array( $rule ) ? $rule : [], [ 'type' => 'url', 'operator' => 'contains', 'value' => '' ] );
										$value_input = '<input type="text" class="wpps-cs-rule-value wpps-cs-input wpps-cs-rule-value-text" value="' . esc_attr( $r['value'] ) . '" placeholder="' . esc_attr__( 'Value', 'wp-powersuite' ) . '">';
										if ( $r['type'] === 'type_of_page' ) {
											$value_input = '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">';
											foreach ( $page_types as $val => $label ) {
												$value_input .= '<option value="' . esc_attr( $val ) . '"' . selected( $r['value'], $val, false ) . '>' . esc_html( $label ) . '</option>';
											}
											$value_input .= '</select>';
										} elseif ( $r['type'] === 'post_type' ) {
											$value_input = '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">';
											foreach ( $post_types as $val => $label ) {
												$value_input .= '<option value="' . esc_attr( $val ) . '"' . selected( $r['value'], $val, false ) . '>' . esc_html( $label ) . '</option>';
											}
											$value_input .= '</select>';
										} elseif ( $r['type'] === 'user_role' ) {
											$value_input = '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">';
											foreach ( $user_roles as $val => $label ) {
												$value_input .= '<option value="' . esc_attr( $val ) . '"' . selected( $r['value'], $val, false ) . '>' . esc_html( $label ) . '</option>';
											}
											$value_input .= '</select>';
										} elseif ( $r['type'] === 'logged_in' ) {
											$value_input = '<select class="wpps-cs-rule-value wpps-cs-rule-value-select"><option value="1"' . selected( $r['value'], '1', false ) . '>' . esc_html__( 'Yes', 'wp-powersuite' ) . '</option><option value="0"' . selected( $r['value'], '0', false ) . '>' . esc_html__( 'No', 'wp-powersuite' ) . '</option></select>';
										}
										?>
									<div class="wpps-cs-conditional-rule" data-index="<?php echo (int) $ri; ?>">
										<select class="wpps-cs-rule-type">
											<option value="url" <?php selected( $r['type'], 'url' ); ?>><?php esc_html_e( 'URL', 'wp-powersuite' ); ?></option>
											<option value="user_role" <?php selected( $r['type'], 'user_role' ); ?>><?php esc_html_e( 'User Role', 'wp-powersuite' ); ?></option>
											<option value="logged_in" <?php selected( $r['type'], 'logged_in' ); ?>><?php esc_html_e( 'Logged In', 'wp-powersuite' ); ?></option>
											<option value="type_of_page" <?php selected( $r['type'], 'type_of_page' ); ?>><?php esc_html_e( 'Type of Page', 'wp-powersuite' ); ?></option>
											<option value="post_type" <?php selected( $r['type'], 'post_type' ); ?>><?php esc_html_e( 'Post Type', 'wp-powersuite' ); ?></option>
										</select>
										<select class="wpps-cs-rule-operator">
											<option value="contains" <?php selected( $r['operator'], 'contains' ); ?>><?php esc_html_e( 'contains', 'wp-powersuite' ); ?></option>
											<option value="not_contains" <?php selected( $r['operator'], 'not_contains' ); ?>><?php esc_html_e( 'does not contain', 'wp-powersuite' ); ?></option>
											<option value="equals" <?php selected( $r['operator'], 'equals' ); ?>><?php esc_html_e( 'equals', 'wp-powersuite' ); ?></option>
											<option value="not_equals" <?php selected( $r['operator'], 'not_equals' ); ?>><?php esc_html_e( 'does not equal', 'wp-powersuite' ); ?></option>
										</select>
										<span class="wpps-cs-rule-value-wrap"><?php echo $value_input; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?></span>
										<button type="button" class="wpps-cs-rule-remove">&times;</button>
									</div>
									<?php endforeach; ?>
								</div>
								<div class="wpps-cs-group-actions">
									<button type="button" class="wpps-cs-conditional-add-rule wpps-cs-btn wpps-cs-btn-secondary"><?php esc_html_e( 'Add Rule', 'wp-powersuite' ); ?></button>
									<?php if ( $gi > 0 ) : ?>
									<button type="button" class="wpps-cs-group-remove wpps-cs-btn wpps-cs-btn-secondary"><?php esc_html_e( 'Remove Group', 'wp-powersuite' ); ?></button>
									<?php endif; ?>
								</div>
							</div>
							<?php endforeach; ?>
						</div>
						<button type="button" id="wpps-cs-conditional-add-group" class="wpps-cs-btn wpps-cs-btn-secondary"><?php esc_html_e( 'Add Rule Group (OR)', 'wp-powersuite' ); ?></button>
					</div>
				</div>
			</div>

			<!-- 4. Code Revisions -->
			<div class="wpps-cs-accordion <?php echo ! $is_pro ? 'wpps-cs-accordion-pro' : ''; ?>" data-accordion-id="revisions">
				<button type="button" class="wpps-cs-accordion-header" aria-expanded="false" aria-controls="wpps-cs-accordion-revisions">
					<span class="wpps-cs-accordion-title">
						<?php esc_html_e( 'Code Revisions', 'wp-powersuite' ); ?><?php if ( ! $is_pro && function_exists( 'wpps_render_premium_badge' ) ) { wpps_render_premium_badge(); } ?>
						<span class="wpps-cs-accordion-tooltip" aria-label="<?php esc_attr_e( 'Help', 'wp-powersuite' ); ?>"><span class="wpps-cs-accordion-tooltip-trigger">?</span><span class="wpps-cs-accordion-tooltip-panel"><?php esc_html_e( 'As you make changes and save, previous versions are stored. Compare revisions or restore any revision from the dedicated revisions page.', 'wp-powersuite' ); ?></span></span>
					</span>
					<span class="dashicons dashicons-arrow-down-alt2 wpps-cs-accordion-chevron"></span>
				</button>
				<div id="wpps-cs-accordion-revisions" class="wpps-cs-accordion-body">
					<?php if ( ! $is_pro ) : ?>
						<div class="wpps-cs-pro-overlay">
							<span class="dashicons dashicons-lock"></span>
							<p><?php esc_html_e( 'Code Revisions is a PRO feature.', 'wp-powersuite' ); ?></p>
							<a href="<?php echo esc_url( $license_page_url ); ?>" class="wpps-cs-btn wpps-cs-btn-primary"<?php echo $upsell_attrs; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static attribute string. ?>><?php echo esc_html( $upsell_label ); ?></a>
						</div>
					<?php endif; ?>
					<label class="wpps-cs-conditional-toggle">
						<input type="checkbox" id="wpps-cs-revisions-enabled" value="1" <?php checked( ! empty( $d['revisions_enabled'] ) ); ?> <?php disabled( ! $is_pro ); ?>>
						<?php esc_html_e( 'Enable revisions', 'wp-powersuite' ); ?>
					</label>
					<div id="wpps-cs-revisions-list-wrap" class="wpps-cs-revisions-list-wrap" style="<?php echo ! empty( $d['revisions_enabled'] ) ? '' : 'display:none;'; ?>">
						<p class="wpps-cs-revisions-desc"><?php esc_html_e( 'As you make changes to your snippet and save, previous versions are stored. Compare or restore any revision below.', 'wp-powersuite' ); ?></p>
						<?php if ( $is_edit && $d['id'] > 0 ) : ?>
							<div id="wpps-cs-revisions-loading" class="wpps-cs-revisions-loading" style="display:none;"><?php esc_html_e( 'Loading...', 'wp-powersuite' ); ?></div>
							<div id="wpps-cs-revisions-empty" class="wpps-cs-revisions-empty" style="display:none;"><?php esc_html_e( 'No revisions yet. Save your snippet to start tracking.', 'wp-powersuite' ); ?></div>
							<div id="wpps-cs-revisions-list" class="wpps-cs-revisions-list"></div>
							<div id="wpps-cs-revisions-load-more-wrap" class="wpps-cs-revisions-load-more-wrap" style="display:none;">
								<button type="button" id="wpps-cs-revisions-load-more" class="wpps-cs-btn wpps-cs-btn-secondary">
									<span class="wpps-cs-load-more-text"><?php esc_html_e( 'Load more', 'wp-powersuite' ); ?></span>
									<span class="wpps-cs-load-more-spinner" style="display:none;"><span class="wpps-cs-spinner wpps-cs-spinner-secondary"></span> <?php echo esc_html( __( 'Loading...', 'wp-powersuite' ) ); ?></span>
								</button>
							</div>
						<?php else : ?>
							<p class="wpps-cs-revisions-save-first"><?php esc_html_e( 'Save your snippet to start tracking revisions.', 'wp-powersuite' ); ?></p>
						<?php endif; ?>
					</div>
				</div>
			</div>

			<!-- 5. Basic info -->
			<div class="wpps-cs-accordion" data-accordion-id="basic">
				<button type="button" class="wpps-cs-accordion-header" aria-expanded="false" aria-controls="wpps-cs-accordion-basic">
					<span class="wpps-cs-accordion-title">
						<?php esc_html_e( 'Basic info', 'wp-powersuite' ); ?>
						<span class="wpps-cs-accordion-tooltip" aria-label="<?php esc_attr_e( 'Help', 'wp-powersuite' ); ?>"><span class="wpps-cs-accordion-tooltip-trigger">?</span><span class="wpps-cs-accordion-tooltip-panel"><?php esc_html_e( 'Internal notes for your reference.', 'wp-powersuite' ); ?></span></span>
					</span>
					<span class="dashicons dashicons-arrow-down-alt2 wpps-cs-accordion-chevron"></span>
				</button>
				<div id="wpps-cs-accordion-basic" class="wpps-cs-accordion-body">
					<div class="wpps-cs-form-group">
						<label for="wpps-cs-priority"><?php esc_html_e( 'Priority', 'wp-powersuite' ); ?></label>
						<input type="number" id="wpps-cs-priority" class="wpps-cs-input wpps-cs-input-sm" value="<?php echo (int) $d['priority']; ?>" data-wpps-min="1" data-wpps-max="999" data-wpps-step="1">
						<span class="wpps-cs-help"><?php esc_html_e( 'When several snippets use the same place, a lower number runs first. If two share the same number, the snippet with the smaller ID runs first. Site-wide header, body, and footer (and admin header/footer) run their snippets together in this order when that part of the page is built.', 'wp-powersuite' ); ?></span>
					</div>
					<div class="wpps-cs-form-group">
						<label for="wpps-cs-notes"><?php esc_html_e( 'Notes', 'wp-powersuite' ); ?></label>
						<textarea id="wpps-cs-notes" class="wpps-cs-input" rows="3" placeholder="<?php esc_attr_e( 'Optional notes about this snippet...', 'wp-powersuite' ); ?>"><?php echo esc_textarea( $d['notes'] ?? '' ); ?></textarea>
						<span class="wpps-cs-help"><?php esc_html_e( 'Internal notes for your reference.', 'wp-powersuite' ); ?></span>
					</div>
				</div>
			</div>
		</div>
		</div><!-- .wpps-cs-edit-stack -->

		<!-- Footer actions -->
		<div class="wpps-cs-edit-actions">
			<?php if ( $is_edit ) : ?>
				<button type="button" id="wpps-cs-delete-btn" class="wpps-cs-btn wpps-cs-btn-danger"><?php esc_html_e( 'Delete Snippet', 'wp-powersuite' ); ?></button>
			<?php endif; ?>
			<div class="wpps-cs-edit-actions-right">
				<a href="<?php echo esc_url( $list_url ); ?>" class="wpps-cs-btn wpps-cs-btn-secondary"><?php esc_html_e( 'Cancel', 'wp-powersuite' ); ?></a>
			</div>
		</div>
	</form>

	<!-- Code Type Selection Modal -->
	<div id="wpps-cs-code-type-modal" class="wpps-cs-modal" role="dialog" aria-labelledby="wpps-cs-code-type-modal-title" aria-modal="true" aria-hidden="true">
		<div class="wpps-cs-modal-backdrop"></div>
		<div class="wpps-cs-modal-content">
			<div class="wpps-cs-modal-header">
				<h2 id="wpps-cs-code-type-modal-title"><?php esc_html_e( 'Select the code type for your snippet:', 'wp-powersuite' ); ?></h2>
				<button type="button" class="wpps-cs-modal-close" aria-label="<?php esc_attr_e( 'Close', 'wp-powersuite' ); ?>">&times;</button>
			</div>
			<div class="wpps-cs-modal-body">
				<div class="wpps-cs-code-type-grid">
					<?php foreach ( $code_types as $k => $v ) : ?>
						<?php $is_pro_type = ! empty( $v['is_pro'] ); $is_locked = $is_pro_type && ! $is_pro; ?>
						<button type="button" class="wpps-cs-code-type-card <?php echo $d['code_type'] === $k ? 'is-selected' : ''; ?> <?php echo $is_locked ? 'wpps-cs-pro-locked' : ''; ?>" data-type="<?php echo esc_attr( $k ); ?>" data-is-pro="<?php echo $is_pro_type ? '1' : '0'; ?>">
							<span class="wpps-cs-code-type-card-title"><?php echo esc_html( $v['label'] ); ?><?php if ( $is_pro_type && function_exists( 'wpps_render_premium_badge' ) ) { wpps_render_premium_badge(); } ?></span>
							<span class="wpps-cs-code-type-card-desc"><?php echo esc_html( $v['desc'] ); ?></span>
							<?php if ( $is_locked ) : ?>
								<span class="wpps-cs-pro-lock-overlay"><span class="dashicons dashicons-lock"></span> <?php echo esc_html( $upsell_label ); ?></span>
							<?php endif; ?>
						</button>
					<?php endforeach; ?>
				</div>
			</div>
		</div>
	</div>

	<!-- Location selection modal (grouped by category) -->
	<div id="wpps-cs-location-modal" class="wpps-cs-modal" role="dialog" aria-labelledby="wpps-cs-location-modal-title" aria-modal="true" aria-hidden="true">
		<div class="wpps-cs-modal-backdrop"></div>
		<div class="wpps-cs-modal-content wpps-cs-location-modal-content">
			<div class="wpps-cs-modal-header">
				<h2 id="wpps-cs-location-modal-title"><?php esc_html_e( 'Select insertion location:', 'wp-powersuite' ); ?></h2>
				<button type="button" class="wpps-cs-modal-close wpps-cs-location-modal-close" aria-label="<?php esc_attr_e( 'Close', 'wp-powersuite' ); ?>">&times;</button>
			</div>
			<div class="wpps-cs-location-modal-body">
				<div class="wpps-cs-location-modal-sidebar">
					<div class="wpps-cs-location-modal-search">
						<span class="dashicons dashicons-search"></span>
						<input type="text" id="wpps-cs-location-search" placeholder="<?php esc_attr_e( 'Search locations', 'wp-powersuite' ); ?>" autocomplete="off">
					</div>
					<ul class="wpps-cs-location-modal-categories">
						<?php foreach ( $locations_ui as $cat_key => $cat ) : ?>
						<?php $cat_requires_woo = ( $cat_key === 'ecommerce' ); ?>
						<li>
							<button type="button" class="wpps-cs-location-cat-btn <?php echo $cat_key === 'global' ? 'is-active' : ''; ?>" data-category="<?php echo esc_attr( $cat_key ); ?>" data-requires-woo="<?php echo $cat_requires_woo ? '1' : '0'; ?>">
								<?php echo esc_html( $cat['label'] ); ?>
							</button>
						</li>
						<?php endforeach; ?>
					</ul>
				</div>
				<div class="wpps-cs-location-modal-list-wrap">
					<ul class="wpps-cs-location-modal-list">
						<?php foreach ( $locations_ui as $cat_key => $cat ) : ?>
						<?php $cat_requires_woo = ( $cat_key === 'ecommerce' ); ?>
						<?php foreach ( $cat['sections'] as $section ) : ?>
						<li class="wpps-cs-location-modal-separator" data-category="<?php echo esc_attr( $cat_key ); ?>"<?php echo ! empty( $section['php_only'] ) ? ' data-php-only-section="1"' : ''; ?><?php echo ! empty( $section['css_selector'] ) ? ' data-css-selector-section="1"' : ''; ?>>
							<?php echo esc_html( $section['heading'] ); ?>
						</li>
						<?php foreach ( $section['locations'] as $loc ) : ?>
						<?php
						$is_php_only = in_array( $loc['value'], $php_only_locations, true );
						$is_woo_loc  = in_array( $loc['value'], $woo_locations, true );
						?>
						<li class="wpps-cs-location-modal-item <?php echo $d['location'] === $loc['value'] ? 'is-selected' : ''; ?>" data-category="<?php echo esc_attr( $cat_key ); ?>" data-value="<?php echo esc_attr( $loc['value'] ); ?>" data-label="<?php echo esc_attr( $loc['label'] ); ?>" data-php-only="<?php echo $is_php_only ? '1' : '0'; ?>" data-requires-woo="<?php echo $is_woo_loc ? '1' : '0'; ?>">
							<label>
								<span class="wpps-cs-location-item-title"><?php echo esc_html( $loc['label'] ); ?></span>
								<span class="wpps-cs-location-item-desc"><?php echo esc_html( $loc['desc'] ); ?></span>
							</label>
						</li>
						<?php endforeach; ?>
						<?php endforeach; ?>
						<?php endforeach; ?>
					</ul>
				</div>
			</div>
		</div>
	</div>

</div>

<script>
(function() {
	var $ = jQuery;
	var ajaxurl = <?php echo wp_json_encode( $ajax_url ); ?>;
	var nonce = <?php echo wp_json_encode( $nonce ); ?>;
	var listUrl = <?php echo wp_json_encode( $list_url ); ?>;
	var editUrlBase = <?php echo wp_json_encode( admin_url( 'admin.php?page=powersuite-code-snippet&action=edit&id=' ) ); ?>;
	var wooInstalled = <?php echo $woo_installed ? 'true' : 'false'; ?>;
	var phpOnlyLocations = <?php echo wp_json_encode( $php_only_locations, JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
	var fePhpMergeEnabled = <?php echo $merge_fe_ui ? 'true' : 'false'; ?>;
	var fePhpSettingsUrl = <?php echo wp_json_encode( $cs_settings_url ); ?>;
	var fePhpHintMerged = <?php echo wp_json_encode( __( 'Frontend Only PHP runs together with your other Frontend Only PHP snippets (from the database) in one step. If one snippet hits a serious error, the others may not run until it is fixed.', 'wp-powersuite' ) ); ?>;
	var fePhpHintMergedTail = <?php echo wp_json_encode( __( 'Turn off merging under', 'wp-powersuite' ) ); ?>;
	var fePhpHintSeparate = <?php echo wp_json_encode( __( 'Frontend Only PHP runs one snippet at a time. A problem in another snippet is less likely to block this one. You can enable merging in settings if you want a single combined run.', 'wp-powersuite' ) ); ?>;
	var fePhpSettingsLabel = <?php echo wp_json_encode( __( 'Code Snippet settings', 'wp-powersuite' ) ); ?>;
	var codeEditor = null;
	var phpReadOnlyMark = null;
	var jsReadOnlyMarks = [];
	var formDirty = false;
	function markDirty() { formDirty = true; }
	function clearDirty() { formDirty = false; }
	var modeMap = { html: 'htmlmixed', css: 'text/css', js: 'text/javascript', php: 'application/x-httpd-php' };
	var PHP_PREFIX = '<' + '?php';
	var JS_OPEN = '<' + 'script>';
	var JS_CLOSE = '<' + '/' + 'script>';

	var toastTimeout = null;
	function showNotice(msg, type) {
		type = type || 'success';
		var notice = document.getElementById('wpps-cs-edit-notice');
		var msgEl = document.getElementById('wpps-cs-edit-notice-message');
		if (notice && msgEl) {
			notice.className = 'notice notice-' + (type === 'error' ? 'error' : 'success') + ' is-dismissible wpps-cs-inline-notice';
			msgEl.textContent = msg;
			notice.hidden = false;
		}
		var toast = document.getElementById('wpps-cs-toast');
		var toastMsg = document.getElementById('wpps-cs-toast-message');
		if (toast && toastMsg) {
			clearTimeout(toastTimeout);
			toast.className = 'wpps-cs-toast wpps-cs-toast-' + (type === 'error' ? 'error' : 'success');
			toastMsg.textContent = msg;
			toast.setAttribute('aria-hidden', 'false');
			toast.classList.add('is-visible');
			toastTimeout = setTimeout(function() {
				toast.classList.remove('is-visible');
				toast.setAttribute('aria-hidden', 'true');
			}, 3500);
		}
	}

	function markPhpPrefixReadOnly() {
		if (!codeEditor || !codeEditor.codemirror) return;
		var cm = codeEditor.codemirror;
		var type = document.getElementById('wpps-cs-code-type').value;
		if (type !== 'php') return;
		if (phpReadOnlyMark) {
			phpReadOnlyMark.clear();
			phpReadOnlyMark = null;
		}
		var val = cm.getValue();
		if (val.indexOf(PHP_PREFIX) !== 0) return;
		phpReadOnlyMark = cm.markText(
			{ line: 0, ch: 0 },
			{ line: 0, ch: Math.min(PHP_PREFIX.length, cm.getLine(0).length) },
			{ readOnly: true, atomic: true, inclusiveLeft: true, inclusiveRight: false, selectLeft: false, selectRight: false, className: 'wpps-cs-php-prefix-noselect' }
		);
	}

	function stripPhpPrefix(val) {
		var trimmed = (val || '').replace(/^\s+/, '');
		if (trimmed.indexOf(PHP_PREFIX) === 0) {
			return trimmed.slice(PHP_PREFIX.length).replace(/^\s*\n?/, '');
		}
		return val;
	}

	function encodeSnippetCodeForSave(val) {
		try {
			return btoa(unescape(encodeURIComponent(val || '')));
		} catch (e) {
			return '';
		}
	}

	function stripJsWrapper(val) {
		var s = (val || '').trim();
		// Strip multiple outer script tag wrappers (like PHP double-prefix fix).
		while (s.length > 0 && s.toLowerCase().indexOf('<' + 'script') === 0) {
			var tagEnd = s.indexOf('>', 0);
			if (tagEnd === -1) break;
			var afterOpen = s.slice(tagEnd + 1).replace(/^\s*\n?/, '');
			var closeIdx = afterOpen.toLowerCase().lastIndexOf('<' + '/' + 'script>');
			if (closeIdx === -1) return afterOpen;
			s = afterOpen.slice(0, closeIdx).replace(/\n\s*$/, '').trim();
		}
		return s;
	}

	function ensurePhpPrefix(val) {
		var type = document.getElementById('wpps-cs-code-type').value;
		if (type !== 'php') return val;
		var trimmed = val.replace(/^\s+/, '');
		if (trimmed.indexOf(PHP_PREFIX) !== 0) {
			return PHP_PREFIX + '\n' + val;
		}
		return val;
	}

	function markJsWrapperReadOnly() {
		if (!codeEditor || !codeEditor.codemirror) return;
		var cm = codeEditor.codemirror;
		var type = document.getElementById('wpps-cs-code-type').value;
		if (type !== 'js') return;
		jsReadOnlyMarks.forEach(function(m) { if (m) m.clear(); });
		jsReadOnlyMarks = [];
		var val = cm.getValue();
		var firstLine = cm.getLine(0) || '';
		var lastLineNum = cm.lineCount() - 1;
		var lastLine = lastLineNum >= 0 ? cm.getLine(lastLineNum) || '' : '';
		if (firstLine.indexOf(JS_OPEN) === 0) {
			jsReadOnlyMarks.push(cm.markText(
				{ line: 0, ch: 0 },
				{ line: 0, ch: Math.min(JS_OPEN.length, firstLine.length) },
				{ readOnly: true, atomic: true, inclusiveLeft: true, inclusiveRight: false, selectLeft: false, selectRight: false, className: 'wpps-cs-php-prefix-noselect' }
			));
		}
		if (lastLineNum > 0 && lastLine.indexOf(JS_CLOSE) >= 0) {
			var closeStart = lastLine.indexOf(JS_CLOSE);
			jsReadOnlyMarks.push(cm.markText(
				{ line: lastLineNum, ch: closeStart },
				{ line: lastLineNum, ch: Math.min(closeStart + JS_CLOSE.length, lastLine.length) },
				{ readOnly: true, atomic: true, inclusiveLeft: false, inclusiveRight: true, selectLeft: false, selectRight: false, className: 'wpps-cs-php-prefix-noselect' }
			));
		}
	}

	function ensureJsWrapper(val) {
		var type = document.getElementById('wpps-cs-code-type').value;
		if (type !== 'js') return val;
		var trimmed = val.replace(/^\s+/, '');
		var needsOpen = trimmed.indexOf(JS_OPEN) !== 0;
		var needsClose = trimmed.length === 0 || trimmed.lastIndexOf(JS_CLOSE) !== trimmed.length - JS_CLOSE.length;
		if (needsOpen) val = JS_OPEN + '\n' + val;
		if (needsClose) val = val + (val ? '\n' : '') + JS_CLOSE;
		return val;
	}

	function initCodeEditor() {
		var ta = document.getElementById('wpps-cs-code');
		if (!ta || !window.wp || !window.wp.codeEditor) return;
		var wrap = document.querySelector('.wpps-cs-edit-wrap');
		var editorAuto = wrap && wrap.getAttribute('data-editor-auto') === '1';
		var editorHeight = wrap ? parseInt(wrap.getAttribute('data-editor-height'), 10) || 300 : 300;
		var mode = modeMap[document.getElementById('wpps-cs-code-type').value] || 'htmlmixed';
		var cmOpts = {
			mode: mode,
			lineNumbers: true,
			lineWrapping: true,
			styleActiveLine: true,
			matchBrackets: true,
			autoCloseBrackets: true,
			indentUnit: 4,
			tabSize: 4,
			indentWithTabs: false
		};
		if (editorAuto) {
			cmOpts.viewPortMargin = Infinity;
		} else {
			cmOpts.height = editorHeight + 'px';
		}
		codeEditor = window.wp.codeEditor.initialize(ta, { codemirror: cmOpts });
		if (codeEditor && codeEditor.codemirror) {
			var cm = codeEditor.codemirror;
			cm.setOption('extraKeys', {
				'Ctrl-S': function() { $('#wpps-cs-save-btn').trigger('click'); },
				'Cmd-S': function() { $('#wpps-cs-save-btn').trigger('click'); },
				'Ctrl-F': 'findPersistent',
				'Cmd-F': 'findPersistent'
			});
			cm.setOption('styleActiveLine', { nonEmpty: true });
			cm.refresh();
			markPhpPrefixReadOnly();
			markJsWrapperReadOnly();
			updateStatusBarLang();
			updateStatusBarPos();
			cm.on('cursorActivity', updateStatusBarPos);
			cm.on('change', function() {
				markDirty();
				var type = document.getElementById('wpps-cs-code-type').value;
				var val = cm.getValue();
				if (type === 'php') {
					if (val.indexOf(PHP_PREFIX) !== 0) {
						cm.setValue(ensurePhpPrefix(val));
						markPhpPrefixReadOnly();
					}
				} else if (type === 'js') {
					var trimmed = val.replace(/^\s+/, '');
					var needsOpen = trimmed.indexOf(JS_OPEN) !== 0;
					var needsClose = trimmed.length < JS_CLOSE.length || trimmed.lastIndexOf(JS_CLOSE) !== trimmed.length - JS_CLOSE.length;
					if (needsOpen || needsClose) {
						cm.setValue(ensureJsWrapper(val));
						markJsWrapperReadOnly();
					}
				}
			});
			window.addEventListener('beforeunload', function(e) {
				if (!formDirty) return;
				e.preventDefault();
				e.returnValue = '';
			});
			$('#wpps-cs-edit-form').on('input change', 'input:not(#wpps-cs-code), textarea:not(#wpps-cs-code), select', markDirty);
		}
		setupEditorTheme();
	}

	var THEME_STORAGE_KEY = 'wppsCsEditorTheme';
	function getStoredTheme() {
		try { return window.localStorage.getItem(THEME_STORAGE_KEY); } catch (e) { return null; }
	}
	function storeTheme(theme) {
		try { window.localStorage.setItem(THEME_STORAGE_KEY, theme); } catch (e) {}
	}
	function applyEditorTheme(theme) {
		var isDark = theme === 'dark';
		var wrap = document.querySelector('.wpps-cs-code-panel .wpps-cs-code-wrap');
		if (wrap) wrap.classList.toggle('wpps-cs-theme-dark', isDark);
		if (codeEditor && codeEditor.codemirror) {
			codeEditor.codemirror.setOption('theme', isDark ? 'wpps-dark' : 'default');
			codeEditor.codemirror.refresh();
		}
		var btn = document.getElementById('wpps-cs-theme-toggle');
		if (btn) {
			btn.setAttribute('aria-pressed', isDark ? 'true' : 'false');
			var label = btn.querySelector('.wpps-cs-theme-toggle-label');
			if (label) label.textContent = isDark ? '<?php echo esc_js( __( 'Light', 'wp-powersuite' ) ); ?>' : '<?php echo esc_js( __( 'Dark', 'wp-powersuite' ) ); ?>';
		}
	}

	function updateStatusBarPos() {
		if (!codeEditor || !codeEditor.codemirror) return;
		var cm = codeEditor.codemirror;
		var c = cm.getCursor();
		var posEl = document.getElementById('wpps-cs-status-pos');
		if (posEl) posEl.textContent = 'Ln ' + (c.line + 1) + ', Col ' + (c.ch + 1);
	}
	function updateStatusBarLang() {
		var langEl = document.getElementById('wpps-cs-status-lang');
		if (langEl) langEl.textContent = (document.getElementById('wpps-cs-code-type').value || 'html').toUpperCase();
	}
	function setupEditorTheme() {
		var theme = getStoredTheme() === 'dark' ? 'dark' : 'light';
		applyEditorTheme(theme);
		var btn = document.getElementById('wpps-cs-theme-toggle');
		if (btn && !btn.dataset.wppsBound) {
			btn.dataset.wppsBound = '1';
			btn.addEventListener('click', function() {
				var next = getStoredTheme() === 'dark' ? 'light' : 'dark';
				storeTheme(next);
				applyEditorTheme(next);
			});
		}
	}

	function getCodeValue() {
		if (codeEditor && codeEditor.codemirror) return codeEditor.codemirror.getValue();
		var ta = document.getElementById('wpps-cs-code');
		return ta ? ta.value : '';
	}

	function setCodeValue(val) {
		if (codeEditor && codeEditor.codemirror) {
			codeEditor.codemirror.setValue(val);
		} else {
			var ta = document.getElementById('wpps-cs-code');
			if (ta) ta.value = val;
		}
	}

	function whenCodeEditorReady(cb) {
		if (window.wp && window.wp.codeEditor) {
			cb();
			return;
		}
		var attempts = 0;
		var iv = setInterval(function() {
			if (window.wp && window.wp.codeEditor) {
				clearInterval(iv);
				cb();
			} else if (++attempts > 40) {
				clearInterval(iv);
			}
		}, 50);
	}

	$(document).ready(function() {
		// Defer CodeMirror init until after first paint to reduce layout jump
		whenCodeEditorReady(function() {
			requestAnimationFrame(function() {
				requestAnimationFrame(initCodeEditor);
			});
		});

		// Wire the theme toggle immediately (re-applied once CodeMirror initializes).
		setupEditorTheme();

		// Prevent tooltip from toggling accordion
		$('.wpps-cs-accordion-tooltip').on('click', function(e) {
			e.stopPropagation();
		});

		// Active toggle label
		$('#wpps-cs-active').on('change', function() {
			$('.wpps-cs-active-label').text(this.checked ? '<?php echo esc_js( __( 'Active', 'wp-powersuite' ) ); ?>' : '<?php echo esc_js( __( 'Inactive', 'wp-powersuite' ) ); ?>');
		});

		// Accordion toggle with persisted state
		var accordionStorageKey = 'wpps_cs_accordion_state';
		var accordionDefaults = { insertion: true, device: false, conditional: false, revisions: false, basic: false };
		function getAccordionState() {
			try {
				var stored = localStorage.getItem(accordionStorageKey);
				return stored ? Object.assign({}, accordionDefaults, JSON.parse(stored)) : accordionDefaults;
			} catch (e) { return accordionDefaults; }
		}
		function saveAccordionState(state) {
			try { localStorage.setItem(accordionStorageKey, JSON.stringify(state)); } catch (e) {}
		}
		function restoreAccordionState() {
			var state = getAccordionState();
			$('.wpps-cs-accordion[data-accordion-id]').each(function() {
				var id = $(this).data('accordion-id');
				var isOpen = state[id] !== false;
				$(this).toggleClass('is-open', isOpen);
				$(this).find('.wpps-cs-accordion-header').attr('aria-expanded', isOpen);
			});
		}
		restoreAccordionState();
		$('.wpps-cs-accordion-header').on('click', function() {
			var $accordion = $(this).closest('.wpps-cs-accordion');
			var id = $accordion.data('accordion-id');
			var isOpen = $accordion.hasClass('is-open');
			$accordion.toggleClass('is-open', !isOpen);
			$(this).attr('aria-expanded', !isOpen);
			if (id) {
				var state = getAccordionState();
				state[id] = !isOpen;
				saveAccordionState(state);
			}
		});

		$('input[name="insert_method"]').on('change', function() {
			var isAuto = $(this).val() === 'auto';
			$('.wpps-cs-insert-btn').removeClass('is-active');
			$(this).closest('.wpps-cs-insert-btn').addClass('is-active');
			$('#wpps-cs-location-wrap').toggle(isAuto);
			$('#wpps-cs-shortcode-wrap').toggle(!isAuto);
		});

		// Shortcode copy buttons
		var COPY_OK_MSG = '<?php echo esc_js( __( 'Shortcode copied to clipboard.', 'wp-powersuite' ) ); ?>';
		var COPY_FAIL_MSG = '<?php echo esc_js( __( 'Could not copy automatically. Press Ctrl/Cmd+C to copy.', 'wp-powersuite' ) ); ?>';
		var COPIED_LABEL = '<?php echo esc_js( __( 'Copied!', 'wp-powersuite' ) ); ?>';

		function legacyCopy(text) {
			var ta = document.createElement('textarea');
			ta.value = text;
			ta.style.position = 'fixed';
			ta.style.top = '-9999px';
			ta.style.opacity = '0';
			document.body.appendChild(ta);
			ta.focus();
			ta.select();
			var ok = false;
			try { ok = document.execCommand('copy'); } catch (e) { ok = false; }
			document.body.removeChild(ta);
			return ok;
		}

		function flashCopied($btn) {
			if (!$btn || !$btn.length) return;
			if ($btn.data('wpps-orig') == null) $btn.data('wpps-orig', $btn.text());
			$btn.addClass('is-copied').text(COPIED_LABEL);
			clearTimeout($btn.data('wpps-copy-timer'));
			var t = setTimeout(function() {
				$btn.removeClass('is-copied').text($btn.data('wpps-orig'));
			}, 1600);
			$btn.data('wpps-copy-timer', t);
		}

		function copyToClipboard(text, $btn) {
			function onSuccess() { flashCopied($btn); showNotice(COPY_OK_MSG); }
			function onFail() { showNotice(COPY_FAIL_MSG, 'error'); }
			if (navigator.clipboard && navigator.clipboard.writeText && window.isSecureContext !== false) {
				navigator.clipboard.writeText(text).then(onSuccess).catch(function() {
					if (legacyCopy(text)) { onSuccess(); } else { onFail(); }
				});
			} else if (legacyCopy(text)) {
				onSuccess();
			} else {
				onFail();
			}
		}
		function updateShortcodeDisplay() {
			var id = parseInt(document.getElementById('wpps-cs-id').value, 10);
			var custom = (document.getElementById('wpps-cs-custom-shortcode') && document.getElementById('wpps-cs-custom-shortcode').value || '').replace(/[^a-z0-9_]/gi, '').toLowerCase();
			var display = document.getElementById('wpps-cs-shortcode-display');
			if (!display) return;
			if (id <= 0) {
				display.value = '<?php echo esc_js( __( 'Please save the snippet first', 'wp-powersuite' ) ); ?>';
			} else if (custom) {
				display.value = '[' + custom + ']';
			} else {
				display.value = '[wpps_code id="' + id + '"]';
			}
		}
		$('#wpps-cs-shortcode-copy').on('click', function() {
			var val = document.getElementById('wpps-cs-shortcode-display').value;
			if (val && val.indexOf('[') === 0) {
				copyToClipboard(val, $(this));
			} else {
				showNotice('<?php echo esc_js( __( 'Save the snippet first to generate its shortcode.', 'wp-powersuite' ) ); ?>', 'error');
			}
		});
		$('#wpps-cs-custom-shortcode-copy').on('click', function() {
			var custom = (document.getElementById('wpps-cs-custom-shortcode').value || '').replace(/[^a-z0-9_]/gi, '').toLowerCase();
			if (custom) {
				copyToClipboard('[' + custom + ']', $(this));
			} else {
				showNotice('<?php echo esc_js( __( 'Enter a custom shortcode name first.', 'wp-powersuite' ) ); ?>', 'error');
			}
		});
		$('#wpps-cs-custom-shortcode').on('input', updateShortcodeDisplay);

		// Location picker modal
		var $locationTrigger = $('#wpps-cs-location-trigger');
		var $locationModal = $('#wpps-cs-location-modal');
		var $locationInput = $('#wpps-cs-location');
		var $locationDisplay = $('#wpps-cs-location-display');
		var $locationSearch = $('#wpps-cs-location-search');

		function updateLocationOptionsState() {
			var codeType = document.getElementById('wpps-cs-code-type') ? document.getElementById('wpps-cs-code-type').value : 'html';
			var isPhp = (codeType === 'php');
			$('.wpps-cs-location-modal-item').each(function() {
				var $opt = $(this);
				var phpOnly = $opt.data('php-only') === 1 || $opt.data('php-only') === '1';
				var requiresWoo = $opt.data('requires-woo') === 1 || $opt.data('requires-woo') === '1';
				var disabled = (!isPhp && phpOnly) || (!wooInstalled && requiresWoo);
				$opt.toggleClass('wpps-cs-location-disabled', disabled);
			});
			$('.wpps-cs-location-cat-btn').each(function() {
				var $btn = $(this);
				if ($btn.data('requires-woo') === 1 || $btn.data('requires-woo') === '1') {
					$btn.toggleClass('wpps-cs-location-disabled', !wooInstalled);
				}
			});
			if ($locationModal.hasClass('is-open')) {
				reorderLocationSectionsForPhp();
				var activeCat = $('.wpps-cs-location-cat-btn.is-active').data('category');
				filterByCategory(activeCat);
			}
			updateFePhpHint();
		}
		function filterByCategory(cat) {
			$('.wpps-cs-location-modal-separator, .wpps-cs-location-modal-item').each(function() {
				var match = (cat === '*' || $(this).data('category') === cat);
				$(this).toggle(match);
			});
		}
		function reorderLocationSectionsForPhp() {
			var codeType = document.getElementById('wpps-cs-code-type') ? document.getElementById('wpps-cs-code-type').value : 'html';
			var $list = $('.wpps-cs-location-modal-list');
			var $phpSep = $list.find('.wpps-cs-location-modal-separator[data-php-only-section="1"]');
			if (!$phpSep.length) return;
			var $phpBlock = $phpSep;
			var $next = $phpSep.next();
			while ($next.length && $next.hasClass('wpps-cs-location-modal-item')) {
				$phpBlock = $phpBlock.add($next);
				$next = $next.next();
			}
			if (codeType === 'php') {
				$list.prepend($phpBlock);
			} else {
				var $cssSep = $list.find('.wpps-cs-location-modal-separator[data-css-selector-section="1"]');
				if ($cssSep.length) {
					var $afterCss = $cssSep.nextUntil('.wpps-cs-location-modal-separator').last();
					if ($afterCss.length) {
						$afterCss.after($phpBlock);
					} else {
						$cssSep.after($phpBlock);
					}
				}
			}
		}
		function openLocationModal() {
			updateLocationOptionsState();
			$locationModal.addClass('is-open').attr('aria-hidden', 'false');
			$locationTrigger.attr('aria-expanded', 'true');
			$locationSearch.val('');
			var currentLoc = $locationInput.val();
			var locCat = $('.wpps-cs-location-modal-item[data-value="' + currentLoc + '"]').data('category');
			var $catBtn = locCat ? $('.wpps-cs-location-cat-btn[data-category="' + locCat + '"]') : null;
			if (locCat && $catBtn && $catBtn.length && !$catBtn.hasClass('wpps-cs-location-disabled')) {
				$('.wpps-cs-location-cat-btn').removeClass('is-active');
				$catBtn.addClass('is-active');
			}
			var activeCat = $('.wpps-cs-location-cat-btn.is-active').data('category');
			reorderLocationSectionsForPhp();
			filterByCategory(activeCat);
			$locationSearch.focus();
		}
		function closeLocationModal() {
			$locationModal.removeClass('is-open').attr('aria-hidden', 'true');
			$locationTrigger.attr('aria-expanded', 'false');
			$locationSearch.val('');
			filterByCategory('*');
		}

		$locationTrigger.on('click', function() {
			openLocationModal();
		});

		$locationModal.find('.wpps-cs-modal-backdrop, .wpps-cs-location-modal-close').on('click', closeLocationModal);
		$(document).on('keydown', function(e) {
			if (e.key === 'Escape' && $locationModal.hasClass('is-open')) {
				closeLocationModal();
			}
		});

		$('.wpps-cs-location-cat-btn').on('click', function() {
			if ($(this).hasClass('wpps-cs-location-disabled')) return;
			var cat = $(this).data('category');
			$('.wpps-cs-location-cat-btn').removeClass('is-active');
			$(this).addClass('is-active');
			filterByCategory(cat);
		});

		$('.wpps-cs-location-modal-item').on('click', function() {
			if ($(this).hasClass('wpps-cs-location-disabled')) return;
			var val = $(this).data('value');
			var label = $(this).data('label');
			$locationInput.val(val);
			$locationDisplay.text(label);
			$('.wpps-cs-location-modal-item').removeClass('is-selected');
			$(this).addClass('is-selected');
			closeLocationModal();
			updateLocationParamWrap();
		});

		$locationSearch.on('input', function() {
			var q = $(this).val().toLowerCase().trim();
			var activeCat = $('.wpps-cs-location-cat-btn.is-active').data('category');
			$('.wpps-cs-location-modal-item').each(function() {
				var $item = $(this);
				var cat = $item.data('category');
				var catMatch = (activeCat === '*' || cat === activeCat);
				var searchMatch = !q || $item.data('label').toLowerCase().indexOf(q) !== -1 || $item.find('.wpps-cs-location-item-desc').text().toLowerCase().indexOf(q) !== -1;
				$item.toggle(catMatch && searchMatch);
			});
			$('.wpps-cs-location-modal-separator').each(function() {
				var $sep = $(this);
				var cat = $sep.data('category');
				var catMatch = (activeCat === '*' || cat === activeCat);
				if (!catMatch) {
					$sep.hide();
					return;
				}
				var anyVisible = false;
				$sep.nextUntil('.wpps-cs-location-modal-separator').filter('.wpps-cs-location-modal-item').each(function() {
					if ($(this).is(':visible')) anyVisible = true;
				});
				$sep.toggle(anyVisible);
			});
		});

		// Location param visibility (paragraph/post number) and selector (element locations)
		var needsParamLocations = ['before_paragraph', 'after_paragraph', 'before_post', 'after_post'];
		var needsSelectorLocations = ['before_element', 'after_element', 'start_element', 'end_element'];
		function updateFePhpHint() {
			var $h = $('#wpps-cs-frontend-only-php-hint');
			if (!$h.length) return;
			var loc = $locationInput.val();
			var type = document.getElementById('wpps-cs-code-type') ? document.getElementById('wpps-cs-code-type').value : 'html';
			if (loc !== 'frontend_only' || type !== 'php') {
				$h.hide().empty();
				return;
			}
			var link = '<a href="' + fePhpSettingsUrl + '">' + fePhpSettingsLabel + '</a>';
			if (fePhpMergeEnabled) {
				$h.html(fePhpHintMerged + ' ' + fePhpHintMergedTail + ' ' + link + '.').show();
			} else {
				$h.html(fePhpHintSeparate + ' ' + link + '.').show();
			}
		}
		function updateLocationParamWrap() {
			var loc = $locationInput.val();
			var showParam = needsParamLocations.indexOf(loc) !== -1;
			var showSelector = needsSelectorLocations.indexOf(loc) !== -1;
			$('#wpps-cs-location-param-wrap').toggle(showParam);
			$('#wpps-cs-location-selector-wrap').toggle(showSelector);
			$('#wpps-cs-location-param-help').text(
				(loc === 'before_post' || loc === 'after_post') ? '<?php echo esc_js( __( 'Post number in archive', 'wp-powersuite' ) ); ?>' : '<?php echo esc_js( __( 'Paragraph number', 'wp-powersuite' ) ); ?>'
			);
			updateFePhpHint();
		}
		updateLocationParamWrap();

		// On load: if code type is not PHP and location is PHP-only, switch to footer
		(function() {
			var codeType = document.getElementById('wpps-cs-code-type') ? document.getElementById('wpps-cs-code-type').value : 'html';
			if (codeType !== 'php') {
				var currentLoc = $locationInput.val();
				if (phpOnlyLocations.indexOf(currentLoc) !== -1) {
					$locationInput.val('footer');
					var $footerOpt = $('.wpps-cs-location-modal-item[data-value="footer"]');
					$locationDisplay.text($footerOpt.length ? $footerOpt.data('label') : 'Footer');
					$('.wpps-cs-location-modal-item').removeClass('is-selected');
					$footerOpt.addClass('is-selected');
					updateLocationParamWrap();
				}
			}
		})();

		// Conditional logic toggle
		$('#wpps-cs-conditional-enabled').on('change', function() {
			$('#wpps-cs-conditional-rules-wrap').toggle(this.checked);
		});

		// Revisions toggle
		$('#wpps-cs-revisions-enabled').on('change', function() {
			$('#wpps-cs-revisions-list-wrap').toggle(this.checked);
			if (this.checked && snippetId > 0 && typeof loadRevisionsList === 'function') {
				loadRevisionsList(true);
			}
		});
		var pageTypes = <?php echo wp_json_encode( $page_types, JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
		var postTypes = <?php echo wp_json_encode( $post_types, JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
		var userRoles = <?php echo wp_json_encode( $user_roles, JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
		function renderRuleValueInput(type, value) {
			value = value || '';
			if (type === 'type_of_page') {
				var opts = '';
				for (var k in pageTypes) opts += '<option value="' + k + '">' + pageTypes[k] + '</option>';
				return '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">' + opts + '</select>';
			}
			if (type === 'post_type') {
				var opts = '';
				for (var k in postTypes) opts += '<option value="' + k + '">' + postTypes[k] + '</option>';
				return '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">' + opts + '</select>';
			}
			if (type === 'user_role') {
				var opts = '';
				for (var k in userRoles) opts += '<option value="' + k + '">' + userRoles[k] + '</option>';
				return '<select class="wpps-cs-rule-value wpps-cs-rule-value-select">' + opts + '</select>';
			}
			if (type === 'logged_in') {
				return '<select class="wpps-cs-rule-value wpps-cs-rule-value-select"><option value="1"><?php echo esc_js( __( 'Yes', 'wp-powersuite' ) ); ?></option><option value="0"><?php echo esc_js( __( 'No', 'wp-powersuite' ) ); ?></option></select>';
			}
			return '<input type="text" class="wpps-cs-rule-value wpps-cs-input wpps-cs-rule-value-text" value="' + (value || '').replace(/"/g, '&quot;') + '" placeholder="<?php echo esc_js( __( 'Value', 'wp-powersuite' ) ); ?>">';
		}
		function updateRuleValueWrap($rule, type, value) {
			$rule.find('.wpps-cs-rule-value-wrap').html(renderRuleValueInput(type, value));
		}
		$(document).on('change', '.wpps-cs-rule-type', function() {
			var $rule = $(this).closest('.wpps-cs-conditional-rule');
			var type = $(this).val();
			updateRuleValueWrap($rule, type, '');
		});
		$(document).on('click', '.wpps-cs-conditional-add-rule', function() {
			var $group = $(this).closest('.wpps-cs-conditional-group');
			var $rules = $group.find('.wpps-cs-conditional-rules');
			var idx = $rules.find('.wpps-cs-conditional-rule').length;
			var $new = $('<div class="wpps-cs-conditional-rule" data-index="' + idx + '">' +
				'<select class="wpps-cs-rule-type"><option value="url"><?php echo esc_js( __( 'URL', 'wp-powersuite' ) ); ?></option><option value="user_role"><?php echo esc_js( __( 'User Role', 'wp-powersuite' ) ); ?></option><option value="logged_in"><?php echo esc_js( __( 'Logged In', 'wp-powersuite' ) ); ?></option><option value="type_of_page"><?php echo esc_js( __( 'Type of Page', 'wp-powersuite' ) ); ?></option><option value="post_type"><?php echo esc_js( __( 'Post Type', 'wp-powersuite' ) ); ?></option></select>' +
				'<select class="wpps-cs-rule-operator"><option value="contains"><?php echo esc_js( __( 'contains', 'wp-powersuite' ) ); ?></option><option value="not_contains"><?php echo esc_js( __( 'does not contain', 'wp-powersuite' ) ); ?></option><option value="equals"><?php echo esc_js( __( 'equals', 'wp-powersuite' ) ); ?></option><option value="not_equals"><?php echo esc_js( __( 'does not equal', 'wp-powersuite' ) ); ?></option></select>' +
				'<span class="wpps-cs-rule-value-wrap">' + renderRuleValueInput('url', '') + '</span>' +
				'<button type="button" class="wpps-cs-rule-remove">&times;</button></div>');
			$rules.append($new);
		});
		$('#wpps-cs-conditional-add-group').on('click', function() {
			var $groups = $('#wpps-cs-conditional-groups');
			var gi = $groups.find('.wpps-cs-conditional-group').length;
			var ruleHtml = '<div class="wpps-cs-conditional-rule" data-index="0"><select class="wpps-cs-rule-type"><option value="url"><?php echo esc_js( __( 'URL', 'wp-powersuite' ) ); ?></option><option value="user_role"><?php echo esc_js( __( 'User Role', 'wp-powersuite' ) ); ?></option><option value="logged_in"><?php echo esc_js( __( 'Logged In', 'wp-powersuite' ) ); ?></option><option value="type_of_page"><?php echo esc_js( __( 'Type of Page', 'wp-powersuite' ) ); ?></option><option value="post_type"><?php echo esc_js( __( 'Post Type', 'wp-powersuite' ) ); ?></option></select><select class="wpps-cs-rule-operator"><option value="contains"><?php echo esc_js( __( 'contains', 'wp-powersuite' ) ); ?></option><option value="not_contains"><?php echo esc_js( __( 'does not contain', 'wp-powersuite' ) ); ?></option><option value="equals"><?php echo esc_js( __( 'equals', 'wp-powersuite' ) ); ?></option><option value="not_equals"><?php echo esc_js( __( 'does not equal', 'wp-powersuite' ) ); ?></option></select><span class="wpps-cs-rule-value-wrap">' + renderRuleValueInput('url', '') + '</span><button type="button" class="wpps-cs-rule-remove">&times;</button></div>';
			var $new = $('<div class="wpps-cs-conditional-group" data-group-index="' + gi + '"><span class="wpps-cs-group-label"><?php echo esc_js( __( 'OR', 'wp-powersuite' ) ); ?></span><div class="wpps-cs-conditional-rules">' + ruleHtml + '</div><div class="wpps-cs-group-actions"><button type="button" class="wpps-cs-conditional-add-rule wpps-cs-btn wpps-cs-btn-secondary"><?php echo esc_js( __( 'Add Rule', 'wp-powersuite' ) ); ?></button><button type="button" class="wpps-cs-group-remove wpps-cs-btn wpps-cs-btn-secondary"><?php echo esc_js( __( 'Remove Group', 'wp-powersuite' ) ); ?></button></div></div>');
			$groups.append($new);
		});
		$(document).on('click', '.wpps-cs-group-remove', function() {
			$(this).closest('.wpps-cs-conditional-group').remove();
		});
		$(document).on('click', '.wpps-cs-rule-remove', function() {
			$(this).closest('.wpps-cs-conditional-rule').remove();
		});

		// Schedule toggle
		$('#wpps-cs-schedule-enabled').on('change', function() {
			$('#wpps-cs-schedule-fields').toggle(this.checked);
		});

		// Device type boxes - toggle is-selected on radio change
		$('.wpps-cs-device-box input[name="device_type"]').on('change', function() {
			$('.wpps-cs-device-box').removeClass('is-selected');
			$(this).closest('.wpps-cs-device-box').addClass('is-selected');
		});

		// Code Revisions list (edit page)
		var snippetId = parseInt(document.getElementById('wpps-cs-id').value, 10);
		var editUrl = '<?php echo esc_js( admin_url( 'admin.php?page=powersuite-code-snippet&action=edit&id=' ) ); ?>' + snippetId;
		var revisionsOffset = 0;
		var revisionsLimit = 5;
		var revisionsCurrentVer = null;
		var revisionsCompareBase = '';
		if (snippetId > 0) {
			function loadRevisionsList(reset) {
				if (!document.getElementById('wpps-cs-revisions-enabled') || !document.getElementById('wpps-cs-revisions-enabled').checked) return;
				reset = reset !== false;
				if (reset) {
					revisionsOffset = 0;
					$('#wpps-cs-revisions-list').empty();
					$('#wpps-cs-revisions-load-more-wrap').hide();
				}
				$('#wpps-cs-revisions-loading').show();
				$('#wpps-cs-revisions-empty').hide();
				$('#wpps-cs-revisions-load-more .wpps-cs-load-more-text').hide();
				$('#wpps-cs-revisions-load-more .wpps-cs-load-more-spinner').show();
				$('#wpps-cs-revisions-load-more').prop('disabled', true);
				$.get(ajaxurl, { action: 'wpps_cs_get_revisions_list', nonce: nonce, snippet_id: snippetId, limit: revisionsLimit, offset: revisionsOffset }, function(r) {
					$('#wpps-cs-revisions-loading').hide();
					$('#wpps-cs-revisions-load-more .wpps-cs-load-more-text').show();
					$('#wpps-cs-revisions-load-more .wpps-cs-load-more-spinner').hide();
					$('#wpps-cs-revisions-load-more').prop('disabled', false);
					if (!r.success || !r.data) return;
					var revs = r.data.revisions || [];
					var currentVer = r.data.current_version || null;
					var compareBase = r.data.compare_url || '';
					var hasMore = r.data.has_more || false;
					if (reset) {
						revisionsCurrentVer = currentVer;
						revisionsCompareBase = compareBase;
						$('#wpps-cs-revisions-empty').hide();
						if (currentVer) {
							var currentCompareUrl = r.data.latest_revision_id ? (compareBase + (compareBase.indexOf('?') >= 0 ? '&' : '?') + 'revision=' + r.data.latest_revision_id) : compareBase;
							var $current = $('<div class="wpps-cs-revision-item wpps-cs-revision-item-current" data-revision-id="0">' +
								'<span class="wpps-cs-revision-dot"></span>' +
								'<span class="wpps-cs-revision-avatar"><img src="" alt="" class="wpps-cs-revision-avatar-img" width="32" height="32"></span>' +
								'<span class="wpps-cs-revision-meta">' +
									'<span class="wpps-cs-revision-current-label"><?php echo esc_js( __( 'Current Version', 'wp-powersuite' ) ); ?></span>' +
									'<span class="wpps-cs-revision-author"></span>' +
									'<span class="wpps-cs-revision-date"></span>' +
								'</span>' +
								'<span class="wpps-cs-revision-actions">' +
									'<a href="' + currentCompareUrl + '" class="wpps-cs-btn wpps-cs-btn-secondary"><?php echo esc_js( __( 'Compare', 'wp-powersuite' ) ); ?></a>' +
								'</span>' +
							'</div>');
							$current.find('.wpps-cs-revision-avatar-img').attr('src', currentVer.avatar || '');
							$current.find('.wpps-cs-revision-author').text(currentVer.author || '');
							$current.find('.wpps-cs-revision-date').text(currentVer.date_fmt || '');
							$('#wpps-cs-revisions-list').append($current);
						}
						if (revs.length === 0 && !currentVer) {
							$('#wpps-cs-revisions-empty').show();
							return;
						}
						if (revs.length === 0) {
							$('#wpps-cs-revisions-empty').text('<?php echo esc_js( __( 'No previous revisions yet.', 'wp-powersuite' ) ); ?>').show();
							return;
						}
					}
					var receivedCount = r.data.revisions.length;
					revs.forEach(function(rev) {
						var compareUrl = compareBase + (compareBase.indexOf('?') >= 0 ? '&' : '?') + 'revision=' + rev.id;
						var actionsHtml = '<a href="' + compareUrl + '" class="wpps-cs-btn wpps-cs-btn-secondary"><?php echo esc_js( __( 'Compare', 'wp-powersuite' ) ); ?></a>' +
							'<button type="button" class="wpps-cs-btn wpps-cs-btn-secondary wpps-cs-revision-restore-btn" data-revision-id="' + rev.id + '"><?php echo esc_js( __( 'Restore', 'wp-powersuite' ) ); ?></button>';
						var $item = $('<div class="wpps-cs-revision-item" data-revision-id="' + rev.id + '">' +
							'<span class="wpps-cs-revision-dot"></span>' +
							'<span class="wpps-cs-revision-avatar"><img src="" alt="" class="wpps-cs-revision-avatar-img" width="32" height="32"></span>' +
							'<span class="wpps-cs-revision-meta">' +
								'<span class="wpps-cs-revision-author"></span>' +
								'<span class="wpps-cs-revision-date"></span>' +
							'</span>' +
							'<span class="wpps-cs-revision-actions">' + actionsHtml + '</span>' +
						'</div>');
						$item.find('.wpps-cs-revision-avatar-img').attr('src', rev.avatar || '');
						$item.find('.wpps-cs-revision-author').text(rev.author || '');
						$item.find('.wpps-cs-revision-date').text(rev.date_fmt || '');
						$('#wpps-cs-revisions-list').append($item);
					});
					revisionsOffset += receivedCount;
					$('#wpps-cs-revisions-load-more-wrap').toggle(hasMore);
				}).fail(function() {
					$('#wpps-cs-revisions-loading').hide();
					$('#wpps-cs-revisions-load-more .wpps-cs-load-more-text').show();
					$('#wpps-cs-revisions-load-more .wpps-cs-load-more-spinner').hide();
					$('#wpps-cs-revisions-load-more').prop('disabled', false);
					$('#wpps-cs-revisions-empty').text('<?php echo esc_js( __( 'Failed to load revisions.', 'wp-powersuite' ) ); ?>').show();
				});
			}
			if (document.getElementById('wpps-cs-revisions-enabled') && document.getElementById('wpps-cs-revisions-enabled').checked) {
				loadRevisionsList(true);
			}
			$('#wpps-cs-revisions-load-more').on('click', function() {
				loadRevisionsList(false);
			});
			$(document).on('click', '.wpps-cs-revision-restore-btn', function(e) {
				e.preventDefault();
				if (!confirm('<?php echo esc_js( __( 'Restore this revision? The current version will be replaced.', 'wp-powersuite' ) ); ?>')) return;
				var $btn = $(this);
				var revId = $btn.data('revision-id');
				$btn.prop('disabled', true);
				$.post(ajaxurl, { action: 'wpps_cs_restore_revision', nonce: nonce, revision_id: revId, snippet_id: snippetId }, function(r) {
					if (r.success) {
						showNotice(r.data.message || '<?php echo esc_js( __( 'Revision restored.', 'wp-powersuite' ) ); ?>');
						window.location.href = editUrl + '&restored=1';
					} else {
						showNotice(r.data && r.data.message ? r.data.message : '<?php echo esc_js( __( 'Restore failed.', 'wp-powersuite' ) ); ?>', 'error');
						$btn.prop('disabled', false);
					}
				}).fail(function() {
					showNotice('<?php echo esc_js( __( 'Request failed.', 'wp-powersuite' ) ); ?>', 'error');
					$btn.prop('disabled', false);
				});
			});
		}

		// Code type modal
		var codeTypeLabels = <?php echo wp_json_encode( array_combine( array_keys( $code_types ), array_column( $code_types, 'label' ) ), JSON_HEX_TAG | JSON_HEX_AMP ); ?>;
		$('#wpps-cs-code-type-trigger').on('click', function() {
			$('#wpps-cs-code-type-modal').addClass('is-open').attr('aria-hidden', 'false');
		});
		function closeCodeTypeModal() {
			$('#wpps-cs-code-type-modal').removeClass('is-open').attr('aria-hidden', 'true');
		}
		$('#wpps-cs-code-type-modal .wpps-cs-modal-backdrop, #wpps-cs-code-type-modal .wpps-cs-modal-close').on('click', closeCodeTypeModal);
		$(document).on('keydown', function(e) {
			if (e.key === 'Escape' && $('#wpps-cs-code-type-modal').hasClass('is-open')) {
				closeCodeTypeModal();
			}
		});
		var isPro = <?php echo $is_pro ? 'true' : 'false'; ?>;
		var licensePageUrl = <?php echo wp_json_encode( $license_page_url ); ?>;
		$('.wpps-cs-code-type-card').on('click', function() {
			var $card = $(this);
			if ($card.hasClass('wpps-cs-pro-locked')) {
				window.location.href = licensePageUrl;
				return;
			}
			var type = $card.data('type');
			$('#wpps-cs-code-type').val(type);
			$('#wpps-cs-code-type-display').text(codeTypeLabels[type] || type);
			$('.wpps-cs-code-type-card').removeClass('is-selected');
			$card.addClass('is-selected');
			if (codeEditor && codeEditor.codemirror) {
				codeEditor.codemirror.setOption('mode', modeMap[type] || 'htmlmixed');
			}
			updateStatusBarLang();
			// Strip old type wrappers before applying new type (prevent PHP/JS tag carryover)
			var code = getCodeValue();
			code = stripPhpPrefix(code);
			code = stripJsWrapper(code);
			if (type === 'php') {
				code = (code.trim() === '') ? '' : code;
				setCodeValue(code ? (PHP_PREFIX + '\n' + code) : PHP_PREFIX + '\n');
				markPhpPrefixReadOnly();
				jsReadOnlyMarks.forEach(function(m) { if (m) m.clear(); });
				jsReadOnlyMarks = [];
			} else if (type === 'js') {
				code = (code.trim() === '') ? '' : code;
				setCodeValue(code ? (JS_OPEN + '\n' + code + '\n' + JS_CLOSE) : (JS_OPEN + '\n\n' + JS_CLOSE));
				markJsWrapperReadOnly();
				if (phpReadOnlyMark) {
					phpReadOnlyMark.clear();
					phpReadOnlyMark = null;
				}
			} else {
				setCodeValue(code);
				if (phpReadOnlyMark) {
					phpReadOnlyMark.clear();
					phpReadOnlyMark = null;
				}
				jsReadOnlyMarks.forEach(function(m) { if (m) m.clear(); });
				jsReadOnlyMarks = [];
			}
			if (type !== 'php') {
				var currentLoc = $locationInput.val();
				if (phpOnlyLocations.indexOf(currentLoc) !== -1) {
					$locationInput.val('footer');
					var $footerOpt = $('.wpps-cs-location-modal-item[data-value="footer"]');
					$locationDisplay.text($footerOpt.length ? $footerOpt.data('label') : 'Footer');
					$('.wpps-cs-location-modal-item').removeClass('is-selected');
					$footerOpt.addClass('is-selected');
					updateLocationParamWrap();
				}
			}
			updateLocationOptionsState();
			closeCodeTypeModal();
		});

		$('#wpps-cs-edit-form').on('submit', function(e) {
			e.preventDefault();
			var $btn = $('#wpps-cs-save-btn');
			var btnText = $btn.data('original-text') || $btn.text();
			if (!$btn.data('original-text')) $btn.data('original-text', btnText);
			$btn.prop('disabled', true).addClass('is-loading').html('<span class="wpps-cs-spinner"></span> ' + '<?php echo esc_js( __( 'Saving...', 'wp-powersuite' ) ); ?>');
			var isAuto = $('input[name="insert_method"]:checked').val() === 'auto';
			var location = isAuto ? document.getElementById('wpps-cs-location').value : 'shortcode';
			var loc = document.getElementById('wpps-cs-location').value;
			var selectorLocs = ['before_element', 'after_element', 'start_element', 'end_element'];
			var locSelector = selectorLocs.indexOf(loc) !== -1 ? (document.getElementById('wpps-cs-location-selector') && document.getElementById('wpps-cs-location-selector').value || '') : '';
			var locElementIndex = selectorLocs.indexOf(loc) !== -1 ? (document.getElementById('wpps-cs-location-element-index') && document.getElementById('wpps-cs-location-element-index').value || '') : '';
			var condRules = { show: document.getElementById('wpps-cs-conditional-show').value, groups: [] };
			$('#wpps-cs-conditional-groups .wpps-cs-conditional-group').each(function() {
				var groupRules = [];
				$(this).find('.wpps-cs-conditional-rule').each(function() {
					var $r = $(this);
					groupRules.push({
						type: $r.find('.wpps-cs-rule-type').val(),
						operator: $r.find('.wpps-cs-rule-operator').val(),
						value: $r.find('.wpps-cs-rule-value').val()
					});
				});
				if (groupRules.length) condRules.groups.push(groupRules);
			});
			var code = getCodeValue();
			var codeType = document.getElementById('wpps-cs-code-type').value;
			if (codeType === 'php') {
				code = stripPhpPrefix(code);
			} else if (codeType === 'js') {
				code = stripJsWrapper(code);
			}
			var data = {
				action: 'wpps_cs_save_snippet',
				nonce: nonce,
				id: document.getElementById('wpps-cs-id').value,
				title: document.getElementById('wpps-cs-title').value,
				code: code,
				code_b64: encodeSnippetCodeForSave(code),
				code_type: document.getElementById('wpps-cs-code-type').value,
				location: location,
				location_param: document.getElementById('wpps-cs-location-param').value,
				location_selector: locSelector,
				location_element_index: locElementIndex,
				custom_shortcode: !isAuto ? (document.getElementById('wpps-cs-custom-shortcode') && document.getElementById('wpps-cs-custom-shortcode').value || '') : '',
				auto_insert: isAuto ? '1' : '0',
				device_type: ($('input[name="device_type"]:checked').val() || 'all'),
				conditional_enabled: document.getElementById('wpps-cs-conditional-enabled').checked ? '1' : '0',
				conditional_show: condRules.show,
				conditional_rules: condRules,
				revisions_enabled: document.getElementById('wpps-cs-revisions-enabled') && document.getElementById('wpps-cs-revisions-enabled').checked ? '1' : '0',
				priority: document.getElementById('wpps-cs-priority').value,
				active: document.getElementById('wpps-cs-active').checked ? '1' : '0',
				schedule_enabled: document.getElementById('wpps-cs-schedule-enabled').checked ? '1' : '0',
				schedule_start: document.getElementById('wpps-cs-schedule-start').value,
				schedule_end: document.getElementById('wpps-cs-schedule-end').value,
				load_as_file: document.getElementById('wpps-cs-load-as-file') && document.getElementById('wpps-cs-load-as-file').checked ? '1' : '0',
				notes: document.getElementById('wpps-cs-notes') ? document.getElementById('wpps-cs-notes').value : ''
			};
			$.post(ajaxurl, data, function(r) {
				if (r.success) {
					clearDirty();
					showNotice(r.data.message || '<?php echo esc_js( __( 'Snippet saved successfully.', 'wp-powersuite' ) ); ?>');
					$btn.prop('disabled', false).removeClass('is-loading').html($btn.data('original-text') || '<?php echo esc_js( __( 'Save Snippet', 'wp-powersuite' ) ); ?>');
					var savedId = r.data.id;
					if (savedId && parseInt(document.getElementById('wpps-cs-id').value, 10) === 0) {
						window.location.href = editUrlBase + savedId;
					} else if (savedId && typeof loadRevisionsList === 'function') {
						loadRevisionsList();
					}
				} else {
					showNotice(r.data && r.data.message ? r.data.message : '<?php echo esc_js( __( 'Could not save snippet. Please try again.', 'wp-powersuite' ) ); ?>', 'error');
					$btn.prop('disabled', false).removeClass('is-loading').html($btn.data('original-text') || '<?php echo esc_js( __( 'Save Snippet', 'wp-powersuite' ) ); ?>');
				}
			}).fail(function() {
				showNotice('<?php echo esc_js( __( 'Request failed. Check your connection and try again.', 'wp-powersuite' ) ); ?>', 'error');
				$btn.prop('disabled', false).removeClass('is-loading').html($btn.data('original-text') || '<?php echo esc_js( __( 'Save Snippet', 'wp-powersuite' ) ); ?>');
			});
		});

		$('#wpps-cs-delete-btn').on('click', function() {
			if (!confirm('<?php echo esc_js( __( 'Delete this snippet? This cannot be undone.', 'wp-powersuite' ) ); ?>')) return;
			var id = document.getElementById('wpps-cs-id').value;
			$.post(ajaxurl, { action: 'wpps_cs_delete_snippet', nonce: nonce, id: id }, function(r) {
				if (r.success) {
					clearDirty();
					window.location.href = listUrl;
				} else {
					showNotice(r.data && r.data.message ? r.data.message : '<?php echo esc_js( __( 'Error.', 'wp-powersuite' ) ); ?>', 'error');
				}
			});
		});
	});
})();
</script>
