<?php
/**
 * Custom Fields - single field row renderer (used server-side and as JS template).
 *
 * @package CustomFields
 * @since 1.0.0
 */

namespace CustomFields;

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

if ( ! function_exists( __NAMESPACE__ . '\\cf_tip' ) ) {
	/**
	 * Render a small help tooltip (shared viewport-aware tooltip pattern).
	 *
	 * @param string $text Help copy.
	 */
	function cf_tip( string $text ): void {
		echo '<span class="wpps-cf-accordion-tooltip" aria-label="' . esc_attr__( 'Help', 'wp-powersuite' ) . '">';
		echo '<span class="wpps-cf-accordion-tooltip-trigger">?</span>';
		echo '<span class="wpps-cf-accordion-tooltip-panel">' . esc_html( $text ) . '</span>';
		echo '</span>';
	}
}

if ( ! function_exists( __NAMESPACE__ . '\\cf_render_field_row' ) ) {
	/**
	 * Render one field row.
	 *
	 * @param int|string           $index Field index (or '__INDEX__' for the JS template).
	 * @param array<string, mixed> $field Field definition.
	 */
	function cf_render_field_row( int|string $index, array $field, array $post_types = [], array $taxonomies = [], string $group_key = '', array $field_targets = [], array $field_key_opts = [] ): void {
		$field = array_merge( Config::defaultField(), $field );

		if ( $post_types === [] ) {
			$excluded      = [
				'attachment', 'wp_block', 'wp_navigation', 'wp_template', 'wp_template_part', 'wp_font_family', 'wp_font_face',
				'elementor_library', 'e-floating-buttons', 'e-landing-page', 'elementor_snippet', 'elementor_font', 'elementor_icons', 'elementor-hf',
				'cartflows_step', 'cartflows_flow', 'sureforms_form',
			];
			$builder_types = class_exists( '\\CptBuilder\\Storage' ) ? ( new \CptBuilder\Storage() )->all() : [];
			foreach ( get_post_types( [ 'show_ui' => true ], 'objects' ) as $pt ) {
				if ( in_array( $pt->name, $excluded, true ) ) {
					continue;
				}
				if ( ! isset( $builder_types[ $pt->name ] ) && ( ! $pt->public || ! $pt->show_in_nav_menus ) ) {
					continue;
				}
				$post_types[ $pt->name ] = (string) ( $pt->labels->singular_name ?? $pt->name );
			}
		}
		if ( $taxonomies === [] ) {
			$tax_excluded  = [ 'post_format', 'nav_menu', 'link_category', 'wp_theme', 'wp_template_part_area' ];
			$builder_taxes = class_exists( '\\CptBuilder\\TaxonomyStorage' ) ? ( new \CptBuilder\TaxonomyStorage() )->all() : [];
			foreach ( get_taxonomies( [ 'show_ui' => true ], 'objects' ) as $tax ) {
				if ( in_array( $tax->name, $tax_excluded, true ) ) {
					continue;
				}
				if ( ! $tax->public && ! isset( $builder_taxes[ $tax->name ] ) ) {
					continue;
				}
				$taxonomies[ $tax->name ] = (string) ( $tax->labels->singular_name ?? $tax->name );
			}
		}

		$i                 = (string) $index;
		$name_prefix       = 'fields[' . $i . ']';
		$id_prefix         = 'cf-field-' . preg_replace( '/[^a-z0-9_]/i', '_', $i );
		$type              = (string) $field['type'];
		$label             = (string) $field['label'];
		$is_choice         = in_array( $type, Config::choiceTypes(), true );
		$is_media          = in_array( $type, Config::mediaTypes(), true );
		$is_multiple_type  = in_array( $type, Config::multipleTypes(), true );
		$is_message        = $type === 'message';
		$field_post_types  = isset( $field['post_types'] ) && is_array( $field['post_types'] ) ? array_map( 'strval', $field['post_types'] ) : [];
		$label_text        = $label !== '' ? $label : __( 'Untitled field', 'wp-powersuite' );
		$field_width       = (string) ( $field['width'] ?? '100' );
		$width_labels      = Config::fieldWidths();
		$field_key         = (string) ( $field['key'] ?? '' );
		$field_key_locked  = $field_key !== '';
		$storage_key       = Config::storesValue( $type ) ? MetaKeys::resolve( $group_key, $field ) : '';
		$is_repeater       = $type === 'repeater';
		$is_flexible       = $type === 'flexible_content';
		$is_clone          = $type === 'clone';
		$is_nested         = in_array( $type, Config::nestedTypes(), true );
		$is_relational     = in_array( $type, Config::relationalTypes(), true );
		$no_scalar_opts    = $is_message || $is_nested;
		$conditional       = isset( $field['conditional'] ) && is_array( $field['conditional'] ) ? $field['conditional'] : Config::defaultField()['conditional'];
		$sub_fields        = isset( $field['sub_fields'] ) && is_array( $field['sub_fields'] ) ? $field['sub_fields'] : [];
		$layouts           = isset( $field['layouts'] ) && is_array( $field['layouts'] ) ? $field['layouts'] : [];
		$allowed_sub_types = NestedFields::allowedSubFieldTypes();
		$grouped_types     = [];
		foreach ( Config::fieldTypes() as $ft_key => $ft ) {
			$grouped_types[ $ft['group'] ][ $ft_key ] = $ft['label'];
		}
		?>
		<div class="cf-field-row collapsed" data-index="<?php echo esc_attr( $i ); ?>">
			<div class="cf-field-row__head">
				<span class="cf-field-row__handle dashicons dashicons-menu" aria-hidden="true"></span>
				<button type="button" class="cf-field-row__toggle" aria-expanded="false" aria-label="<?php esc_attr_e( 'Toggle field', 'wp-powersuite' ); ?>"><span class="dashicons dashicons-arrow-down-alt2" aria-hidden="true"></span></button>
				<span class="cf-field-row__title"><?php echo esc_html( $label_text ); ?></span>
				<span class="cf-field-row__type"><?php echo esc_html( Config::fieldTypes()[ $type ]['label'] ?? $type ); ?></span>
				<?php if ( ! $is_message && $field_width !== '100' && isset( $width_labels[ $field_width ] ) ) : ?>
					<span class="cf-field-row__width-badge"><?php echo esc_html( $width_labels[ $field_width ] ); ?></span>
				<?php endif; ?>
				<span class="cf-field-row__actions">
					<button type="button" class="cf-field-row__duplicate" aria-label="<?php esc_attr_e( 'Duplicate field', 'wp-powersuite' ); ?>" title="<?php esc_attr_e( 'Duplicate field', 'wp-powersuite' ); ?>"><span class="dashicons dashicons-admin-page" aria-hidden="true"></span></button>
					<button type="button" class="cf-field-row__remove" aria-label="<?php esc_attr_e( 'Remove field', 'wp-powersuite' ); ?>" title="<?php esc_attr_e( 'Remove field', 'wp-powersuite' ); ?>"><span class="dashicons dashicons-trash" aria-hidden="true"></span></button>
				</span>
			</div>
			<div class="cf-field-row__body">
				<input type="hidden" class="cf-field-key-input" name="<?php echo esc_attr( $name_prefix ); ?>[key]" value="<?php echo esc_attr( $field_key ); ?>"<?php echo $field_key_locked ? ' data-cf-persisted="1"' : ''; ?>>
				<?php if ( $field_key_locked && Config::storesValue( $type ) && (string) ( $field['name'] ?? '' ) !== '' ) : ?>
					<input type="hidden" class="cf-field-name-input" name="<?php echo esc_attr( $name_prefix ); ?>[name]" value="<?php echo esc_attr( (string) $field['name'] ); ?>">
				<?php endif; ?>

				<div class="cf-field-grid">
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-label"><?php esc_html_e( 'Label', 'wp-powersuite' ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-label" class="regular-text cf-field-label-input" name="<?php echo esc_attr( $name_prefix ); ?>[label]" value="<?php echo esc_attr( $label ); ?>">
					</p>
					<p class="cf-field-control cf-field-storage"<?php echo $no_scalar_opts ? ' hidden' : ''; ?>>
						<span class="cf-field-control__label"><?php esc_html_e( 'Field key', 'wp-powersuite' ); ?><?php cf_tip( __( 'Created from the label when you add the field. Used when saving and in templates.', 'wp-powersuite' ) ); ?></span>
						<?php if ( $field_key_locked ) : ?>
							<code class="cf-field-key-readonly"><?php echo esc_html( $field_key ); ?></code>
							<?php if ( $storage_key !== '' && $storage_key !== $field_key ) : ?>
								<span class="description"><?php esc_html_e( 'Saved as:', 'wp-powersuite' ); ?> <code><?php echo esc_html( $storage_key ); ?></code></span>
							<?php endif; ?>
						<?php else : ?>
							<span class="description cf-field-key-preview"><?php esc_html_e( 'Field key:', 'wp-powersuite' ); ?> <code>—</code></span>
						<?php endif; ?>
					</p>
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-type"><?php esc_html_e( 'Type', 'wp-powersuite' ); ?></label>
						<select id="<?php echo esc_attr( $id_prefix ); ?>-type" class="cf-field-type-input" name="<?php echo esc_attr( $name_prefix ); ?>[type]">
							<?php foreach ( $grouped_types as $group_label => $types_in_group ) : ?>
								<optgroup label="<?php echo esc_attr( $group_label ); ?>">
									<?php foreach ( $types_in_group as $ft_key => $ft_label ) : ?>
										<option value="<?php echo esc_attr( $ft_key ); ?>" <?php selected( $type, $ft_key ); ?>><?php echo esc_html( $ft_label ); ?></option>
									<?php endforeach; ?>
								</optgroup>
							<?php endforeach; ?>
						</select>
					</p>
				</div>

				<p class="cf-field-control">
					<label for="<?php echo esc_attr( $id_prefix ); ?>-instructions"><?php esc_html_e( 'Instructions', 'wp-powersuite' ); ?></label>
					<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-instructions" class="widefat" name="<?php echo esc_attr( $name_prefix ); ?>[instructions]" value="<?php echo esc_attr( (string) $field['instructions'] ); ?>">
				</p>

				<div class="cf-field-grid">
					<p class="cf-field-control cf-field-placeholder"<?php echo Config::typeSupports( $type, 'placeholder' ) ? '' : ' hidden'; ?>>
						<label for="<?php echo esc_attr( $id_prefix ); ?>-placeholder"><?php esc_html_e( 'Placeholder', 'wp-powersuite' ); ?><?php cf_tip( __( 'Hint text shown inside the empty input on the edit screen.', 'wp-powersuite' ) ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-placeholder" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[placeholder]" value="<?php echo esc_attr( (string) $field['placeholder'] ); ?>">
					</p>
					<p class="cf-field-control cf-field-default"<?php echo Config::typeSupports( $type, 'default' ) ? '' : ' hidden'; ?>>
						<label for="<?php echo esc_attr( $id_prefix ); ?>-default"><?php esc_html_e( 'Default value', 'wp-powersuite' ); ?><?php cf_tip( __( 'Shown when nothing has been saved yet. For Yes/No fields use 1. For dropdowns and radio buttons, use one of the choice values.', 'wp-powersuite' ) ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-default" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[default]" value="<?php echo esc_attr( (string) $field['default'] ); ?>">
					</p>
				</div>

				<p class="cf-field-control cf-field-choices"<?php echo $is_choice ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-choices"><?php esc_html_e( 'Choices', 'wp-powersuite' ); ?><?php cf_tip( __( 'One option per line. Use value|Label when the saved value should differ from what is shown.', 'wp-powersuite' ) ); ?></label>
					<textarea id="<?php echo esc_attr( $id_prefix ); ?>-choices" class="widefat code" rows="4" name="<?php echo esc_attr( $name_prefix ); ?>[choices]" placeholder="value|Label"><?php echo esc_textarea( (string) $field['choices'] ); ?></textarea>
					<span class="description"><?php esc_html_e( 'One choice per line. Use "value|Label" to set a separate stored value.', 'wp-powersuite' ); ?></span>
				</p>

				<p class="cf-field-control cf-field-message"<?php echo $is_message ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-message"><?php esc_html_e( 'Message content', 'wp-powersuite' ); ?></label>
					<textarea id="<?php echo esc_attr( $id_prefix ); ?>-message" class="widefat" rows="4" name="<?php echo esc_attr( $name_prefix ); ?>[message_content]"><?php echo esc_textarea( (string) ( $field['message_content'] ?? '' ) ); ?></textarea>
					<span class="description"><?php esc_html_e( 'Display-only text shown to editors. Supports basic HTML.', 'wp-powersuite' ); ?></span>
				</p>

				<div class="cf-field-grid cf-field-bounds"<?php echo Config::typeSupports( $type, 'bounds' ) ? '' : ' hidden'; ?>>
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-min"><?php esc_html_e( 'Minimum', 'wp-powersuite' ); ?><?php cf_tip( __( 'Lowest accepted value. For Date / Time fields use the same format as the field (e.g. 2026-01-31).', 'wp-powersuite' ) ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-min" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[min]" value="<?php echo esc_attr( (string) ( $field['min'] ?? '' ) ); ?>">
					</p>
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-max"><?php esc_html_e( 'Maximum', 'wp-powersuite' ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-max" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[max]" value="<?php echo esc_attr( (string) ( $field['max'] ?? '' ) ); ?>">
					</p>
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-step"><?php esc_html_e( 'Step', 'wp-powersuite' ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-step" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[step]" value="<?php echo esc_attr( (string) ( $field['step'] ?? '' ) ); ?>">
					</p>
				</div>

				<p class="cf-field-control cf-field-rows"<?php echo Config::typeSupports( $type, 'rows' ) ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-rows"><?php esc_html_e( 'Rows', 'wp-powersuite' ); ?><?php cf_tip( __( 'Height of the editor on the edit screen, in text rows.', 'wp-powersuite' ) ); ?></label>
					<input type="number" id="<?php echo esc_attr( $id_prefix ); ?>-rows" class="small-text" name="<?php echo esc_attr( $name_prefix ); ?>[rows]" value="<?php echo esc_attr( (string) ( $field['rows'] ?? 4 ) ); ?>" min="2" max="20">
				</p>

				<p class="cf-field-control cf-field-multiple"<?php echo $is_multiple_type ? '' : ' hidden'; ?>>
					<label>
						<input type="checkbox" name="<?php echo esc_attr( $name_prefix ); ?>[multiple]" value="1" <?php checked( ! empty( $field['multiple'] ) ); ?>>
						<?php esc_html_e( 'Allow multiple selections', 'wp-powersuite' ); ?>
					</label>
				</p>

				<?php /* div, not p: a fieldset inside p gets hoisted out by the HTML parser and escapes the hidden wrapper. */ ?>
				<div class="cf-field-control cf-field-post-types"<?php echo $type === 'post_object' ? '' : ' hidden'; ?>>
					<span class="cf-field-control__label"><?php esc_html_e( 'Filter by post types', 'wp-powersuite' ); ?></span>
					<span class="description"><?php esc_html_e( 'Leave empty to include all public post types.', 'wp-powersuite' ); ?></span>
					<fieldset class="cf-checkbox-grid cf-checkbox-grid--compact">
						<?php foreach ( $post_types as $pt_key => $pt_label ) : ?>
							<label class="cf-check">
								<input type="checkbox" name="<?php echo esc_attr( $name_prefix ); ?>[post_types][]" value="<?php echo esc_attr( $pt_key ); ?>" <?php checked( in_array( $pt_key, $field_post_types, true ) ); ?>>
								<span><?php echo esc_html( $pt_label ); ?></span>
							</label>
						<?php endforeach; ?>
					</fieldset>
				</div>

				<p class="cf-field-control cf-field-taxonomy"<?php echo $type === 'term' ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-taxonomy"><?php esc_html_e( 'Taxonomy', 'wp-powersuite' ); ?></label>
					<select id="<?php echo esc_attr( $id_prefix ); ?>-taxonomy" name="<?php echo esc_attr( $name_prefix ); ?>[taxonomy]">
						<option value="">&mdash;</option>
						<?php foreach ( $taxonomies as $tx_key => $tx_label ) : ?>
							<option value="<?php echo esc_attr( $tx_key ); ?>" <?php selected( (string) ( $field['taxonomy'] ?? '' ), $tx_key ); ?>><?php echo esc_html( $tx_label ); ?></option>
						<?php endforeach; ?>
					</select>
				</p>

				<div class="cf-field-grid cf-field-appearance">
					<p class="cf-field-control cf-field-before-after"<?php echo Config::typeSupports( $type, 'before_after' ) ? '' : ' hidden'; ?>>
						<label for="<?php echo esc_attr( $id_prefix ); ?>-before"><?php esc_html_e( 'Text before', 'wp-powersuite' ); ?><?php cf_tip( __( 'Short text printed just before the input, e.g. a currency symbol.', 'wp-powersuite' ) ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-before" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[before]" value="<?php echo esc_attr( (string) ( $field['before'] ?? '' ) ); ?>">
					</p>
					<p class="cf-field-control cf-field-before-after"<?php echo Config::typeSupports( $type, 'before_after' ) ? '' : ' hidden'; ?>>
						<label for="<?php echo esc_attr( $id_prefix ); ?>-after"><?php esc_html_e( 'Text after', 'wp-powersuite' ); ?><?php cf_tip( __( 'Short text printed just after the input, e.g. a unit like “kg”.', 'wp-powersuite' ) ); ?></label>
						<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-after" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[after]" value="<?php echo esc_attr( (string) ( $field['after'] ?? '' ) ); ?>">
					</p>
					<p class="cf-field-control">
						<label for="<?php echo esc_attr( $id_prefix ); ?>-width"><?php esc_html_e( 'Width', 'wp-powersuite' ); ?><?php cf_tip( __( 'How wide this field is on the edit screen. Two half-width fields sit side by side.', 'wp-powersuite' ) ); ?></label>
						<select id="<?php echo esc_attr( $id_prefix ); ?>-width" name="<?php echo esc_attr( $name_prefix ); ?>[width]">
							<?php foreach ( Config::fieldWidths() as $width_key => $width_label ) : ?>
								<option value="<?php echo esc_attr( $width_key ); ?>" <?php selected( (string) ( $field['width'] ?? '100' ), $width_key ); ?>><?php echo esc_html( $width_label ); ?></option>
							<?php endforeach; ?>
						</select>
					</p>
				</div>

				<p class="cf-field-control cf-field-pattern"<?php echo Config::typeSupports( $type, 'pattern' ) ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-pattern"><?php esc_html_e( 'Format check', 'wp-powersuite' ); ?><?php cf_tip( __( 'Optional. The value must match this pattern when saving.', 'wp-powersuite' ) ); ?></label>
					<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-pattern" class="regular-text code" name="<?php echo esc_attr( $name_prefix ); ?>[pattern]" value="<?php echo esc_attr( (string) ( $field['pattern'] ?? '' ) ); ?>" placeholder="^[A-Z0-9]+$">
					<span class="description"><?php esc_html_e( 'Leave blank to skip format checking.', 'wp-powersuite' ); ?></span>
				</p>

				<p class="cf-field-control cf-field-return"<?php echo $is_media && $type !== 'gallery' ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-return"><?php esc_html_e( 'Return format', 'wp-powersuite' ); ?><?php cf_tip( __( 'What your theme receives: the file ID or the file URL.', 'wp-powersuite' ) ); ?></label>
					<select id="<?php echo esc_attr( $id_prefix ); ?>-return" name="<?php echo esc_attr( $name_prefix ); ?>[return]">
						<option value="id" <?php selected( (string) $field['return'], 'id' ); ?>><?php esc_html_e( 'Attachment ID', 'wp-powersuite' ); ?></option>
						<option value="url" <?php selected( (string) $field['return'], 'url' ); ?>><?php esc_html_e( 'URL', 'wp-powersuite' ); ?></option>
					</select>
				</p>

				<div class="cf-field-control cf-field-nested cf-field-repeater"<?php echo $is_repeater ? '' : ' hidden'; ?>>
					<span class="cf-field-control__label"><?php esc_html_e( 'Sub fields', 'wp-powersuite' ); ?></span>
					<div class="cf-subfields-list" data-prefix="<?php echo esc_attr( $name_prefix ); ?>">
						<?php foreach ( array_values( $sub_fields ) as $si => $sub ) : ?>
							<?php if ( ! is_array( $sub ) ) { continue; } ?>
							<div class="cf-subfield-row" data-index="<?php echo esc_attr( (string) $si ); ?>">
								<input type="text" name="<?php echo esc_attr( $name_prefix ); ?>[sub_fields][<?php echo esc_attr( (string) $si ); ?>][label]" value="<?php echo esc_attr( (string) ( $sub['label'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'Label', 'wp-powersuite' ); ?>">
								<input type="text" name="<?php echo esc_attr( $name_prefix ); ?>[sub_fields][<?php echo esc_attr( $si ); ?>][name]" value="<?php echo esc_attr( (string) ( $sub['name'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'Name', 'wp-powersuite' ); ?>">
								<select name="<?php echo esc_attr( $name_prefix ); ?>[sub_fields][<?php echo esc_attr( (string) $si ); ?>][type]">
									<?php foreach ( $allowed_sub_types as $st ) : ?>
										<option value="<?php echo esc_attr( $st ); ?>" <?php selected( (string) ( $sub['type'] ?? 'text' ), $st ); ?>><?php echo esc_html( Config::fieldTypes()[ $st ]['label'] ?? $st ); ?></option>
									<?php endforeach; ?>
								</select>
								<input type="hidden" name="<?php echo esc_attr( $name_prefix ); ?>[sub_fields][<?php echo esc_attr( (string) $si ); ?>][key]" value="<?php echo esc_attr( (string) ( $sub['key'] ?? '' ) ); ?>">
								<button type="button" class="button-link cf-subfield-remove">&times;</button>
							</div>
						<?php endforeach; ?>
					</div>
					<p><button type="button" class="button button-small cf-add-subfield"><?php esc_html_e( 'Add sub field', 'wp-powersuite' ); ?></button></p>
				</div>

				<div class="cf-field-control cf-field-nested cf-field-flexible"<?php echo $is_flexible ? '' : ' hidden'; ?>>
					<span class="cf-field-control__label"><?php esc_html_e( 'Layouts', 'wp-powersuite' ); ?></span>
					<div class="cf-layouts-list" data-prefix="<?php echo esc_attr( $name_prefix ); ?>">
						<?php foreach ( array_values( $layouts ) as $li => $layout ) : ?>
							<?php if ( ! is_array( $layout ) ) { continue; } ?>
							<div class="cf-layout-row" data-index="<?php echo esc_attr( (string) $li ); ?>">
								<input type="text" name="<?php echo esc_attr( $name_prefix ); ?>[layouts][<?php echo esc_attr( (string) $li ); ?>][key]" value="<?php echo esc_attr( (string) ( $layout['key'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'Layout key', 'wp-powersuite' ); ?>">
								<input type="text" name="<?php echo esc_attr( $name_prefix ); ?>[layouts][<?php echo esc_attr( (string) $li ); ?>][label]" value="<?php echo esc_attr( (string) ( $layout['label'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'Layout label', 'wp-powersuite' ); ?>">
								<textarea name="<?php echo esc_attr( $name_prefix ); ?>[layouts][<?php echo esc_attr( (string) $li ); ?>][sub_fields_json]" class="code" rows="3" placeholder='[{"label":"Title","name":"title","type":"text"}]'><?php
									$layout_subs = isset( $layout['sub_fields'] ) && is_array( $layout['sub_fields'] ) ? $layout['sub_fields'] : [];
									echo esc_textarea( $layout_subs !== [] ? (string) wp_json_encode( $layout_subs, JSON_PRETTY_PRINT ) : '' );
								?></textarea>
								<button type="button" class="button-link cf-layout-remove">&times;</button>
							</div>
						<?php endforeach; ?>
					</div>
					<p><button type="button" class="button button-small cf-add-layout"><?php esc_html_e( 'Add layout', 'wp-powersuite' ); ?></button></p>
					<p class="description"><?php esc_html_e( 'Advanced: define sub fields for each layout as JSON.', 'wp-powersuite' ); ?></p>
				</div>

				<p class="cf-field-control cf-field-clone"<?php echo $is_clone ? '' : ' hidden'; ?>>
					<label for="<?php echo esc_attr( $id_prefix ); ?>-clone"><?php esc_html_e( 'Clone source', 'wp-powersuite' ); ?><?php cf_tip( __( 'Reuse fields from another group. Enter a field key or group|field name.', 'wp-powersuite' ) ); ?></label>
					<input type="text" id="<?php echo esc_attr( $id_prefix ); ?>-clone" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[clone_source]" value="<?php echo esc_attr( (string) ( $field['clone_source'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'field_key or group|field or key1,key2', 'wp-powersuite' ); ?>" list="<?php echo esc_attr( $id_prefix ); ?>-clone-list">
					<datalist id="<?php echo esc_attr( $id_prefix ); ?>-clone-list">
						<?php foreach ( $field_key_opts as $fkey => $flabel ) : ?>
							<option value="<?php echo esc_attr( $fkey ); ?>"><?php echo esc_html( $flabel ); ?></option>
						<?php endforeach; ?>
						<?php foreach ( $field_targets as $tkey => $tlabel ) : ?>
							<option value="<?php echo esc_attr( $tkey ); ?>"><?php echo esc_html( $tlabel ); ?></option>
						<?php endforeach; ?>
					</datalist>
				</p>

				<div class="cf-field-control cf-field-bidirectional"<?php echo $is_relational ? '' : ' hidden'; ?>>
					<label class="cf-check-label">
						<input type="checkbox" name="<?php echo esc_attr( $name_prefix ); ?>[bidirectional]" value="1" <?php checked( ! empty( $field['bidirectional'] ) ); ?>>
						<?php esc_html_e( 'Bidirectional', 'wp-powersuite' ); ?>
						<?php cf_tip( __( 'Keeps linked items in sync both ways when you connect posts, terms, or users.', 'wp-powersuite' ) ); ?>
					</label>
					<input type="text" class="regular-text" name="<?php echo esc_attr( $name_prefix ); ?>[bidirectional_target]" value="<?php echo esc_attr( (string) ( $field['bidirectional_target'] ?? '' ) ); ?>" placeholder="<?php esc_attr_e( 'group_key|field_key', 'wp-powersuite' ); ?>" list="<?php echo esc_attr( $id_prefix ); ?>-bio-list">
					<datalist id="<?php echo esc_attr( $id_prefix ); ?>-bio-list">
						<?php foreach ( $field_targets as $tkey => $tlabel ) : ?>
							<option value="<?php echo esc_attr( $tkey ); ?>"><?php echo esc_html( $tlabel ); ?></option>
						<?php endforeach; ?>
					</datalist>
				</div>

				<div class="cf-field-control cf-field-conditional"<?php echo $is_message ? ' hidden' : ''; ?>>
					<label class="cf-check-label">
						<input type="checkbox" class="cf-conditional-enable" name="<?php echo esc_attr( $name_prefix ); ?>[conditional][enabled]" value="1" <?php checked( ! empty( $conditional['enabled'] ) ); ?>>
						<?php esc_html_e( 'Conditional logic', 'wp-powersuite' ); ?>
						<?php cf_tip( __( 'Show or hide this field based on another field in the same group.', 'wp-powersuite' ) ); ?>
					</label>
					<div class="cf-conditional-panel"<?php echo empty( $conditional['enabled'] ) ? ' hidden' : ''; ?>>
						<div class="cf-conditional-match">
							<span class="cf-conditional-match__label"><?php esc_html_e( 'Show this field when', 'wp-powersuite' ); ?></span>
							<select class="cf-conditional-match-select" name="<?php echo esc_attr( $name_prefix ); ?>[conditional][match]">
								<option value="all" <?php selected( (string) ( $conditional['match'] ?? 'all' ), 'all' ); ?>><?php esc_html_e( 'All rules match (AND)', 'wp-powersuite' ); ?></option>
								<option value="any" <?php selected( (string) ( $conditional['match'] ?? 'all' ), 'any' ); ?>><?php esc_html_e( 'Any rule matches (OR)', 'wp-powersuite' ); ?></option>
							</select>
						</div>
						<div class="cf-conditional-rules">
							<?php foreach ( array_values( (array) ( $conditional['rules'] ?? [] ) ) as $ci => $crule ) : ?>
								<?php if ( ! is_array( $crule ) ) { continue; } ?>
								<div class="cf-conditional-rule-row">
									<select name="<?php echo esc_attr( $name_prefix ); ?>[conditional][rules][<?php echo esc_attr( (string) $ci ); ?>][field]">
										<option value="">&mdash;</option>
										<?php foreach ( $field_key_opts as $fkey => $flabel ) : ?>
											<option value="<?php echo esc_attr( $fkey ); ?>" <?php selected( (string) ( $crule['field'] ?? '' ), $fkey ); ?>><?php echo esc_html( $flabel ); ?></option>
										<?php endforeach; ?>
									</select>
									<select name="<?php echo esc_attr( $name_prefix ); ?>[conditional][rules][<?php echo esc_attr( (string) $ci ); ?>][operator]">
										<?php foreach ( Config::conditionalOperators() as $cop => $cop_label ) : ?>
											<option value="<?php echo esc_attr( $cop ); ?>" <?php selected( (string) ( $crule['operator'] ?? '==' ), $cop ); ?>><?php echo esc_html( $cop_label ); ?></option>
										<?php endforeach; ?>
									</select>
									<span class="cf-conditional-value-wrap" data-cf-name="<?php echo esc_attr( $name_prefix ); ?>[conditional][rules][<?php echo esc_attr( (string) $ci ); ?>][value]" data-cf-selected="<?php echo esc_attr( (string) ( $crule['value'] ?? '' ) ); ?>">
										<input type="text" class="regular-text cf-conditional-value" name="<?php echo esc_attr( $name_prefix ); ?>[conditional][rules][<?php echo esc_attr( (string) $ci ); ?>][value]" value="<?php echo esc_attr( (string) ( $crule['value'] ?? '' ) ); ?>">
									</span>
									<button type="button" class="button-link cf-conditional-rule-remove" aria-label="<?php esc_attr_e( 'Remove condition', 'wp-powersuite' ); ?>">&times;</button>
								</div>
							<?php endforeach; ?>
						</div>
						<button type="button" class="button button-secondary button-small cf-add-conditional-rule"><?php esc_html_e( 'Add condition', 'wp-powersuite' ); ?></button>
					</div>
				</div>

				<div class="cf-field-grid cf-field-flags">
					<p class="cf-field-control cf-field-required"<?php echo $no_scalar_opts ? ' hidden' : ''; ?>>
						<label class="cf-check-label">
							<input type="checkbox" name="<?php echo esc_attr( $name_prefix ); ?>[required]" value="1" <?php checked( ! empty( $field['required'] ) ); ?>>
							<?php esc_html_e( 'Required', 'wp-powersuite' ); ?>
							<?php cf_tip( __( 'Editors must fill in this field before saving.', 'wp-powersuite' ) ); ?>
						</label>
					</p>
					<p class="cf-field-control cf-field-show-list"<?php echo $no_scalar_opts ? ' hidden' : ''; ?>>
						<label class="cf-check-label">
							<input type="checkbox" name="<?php echo esc_attr( $name_prefix ); ?>[show_in_list]" value="1" <?php checked( ! empty( $field['show_in_list'] ) ); ?>>
							<?php esc_html_e( 'Show in admin list table', 'wp-powersuite' ); ?>
							<?php cf_tip( __( 'Adds a column with this value to the posts list.', 'wp-powersuite' ) ); ?>
						</label>
					</p>
				</div>
			</div>
		</div>
		<?php
	}
}

if ( ! function_exists( __NAMESPACE__ . '\\cf_render_field_row_template' ) ) {
	/**
	 * Render the JS row template with an __INDEX__ placeholder.
	 *
	 * @param array<string, string> $post_types Post type choices for relational fields.
	 * @param array<string, string> $taxonomies Taxonomy choices for term fields.
	 */
	function cf_render_field_row_template( array $post_types = [], array $taxonomies = [] ): void {
		cf_render_field_row( '__INDEX__', Config::defaultField(), $post_types, $taxonomies );
	}
}
