import { __ } from '@wordpress/i18n';
import { InspectorControls, useBlockProps, InnerBlocks } from '@wordpress/block-editor';
import {
	PanelBody,
	TextControl,
	ToggleControl,
	RangeControl,
	SelectControl,
	ColorPalette,
	Notice,
	Button,
} from '@wordpress/components';
import { useSelect, dispatch, select } from '@wordpress/data';
import { useState, useEffect, useMemo, useCallback, useRef } from '@wordpress/element';
import { createBlock } from '@wordpress/blocks';
import apiFetch from '@wordpress/api-fetch';
import './editor.scss';

function isSearchableContentPostType( postType ) {
	const visibility = postType?.visibility || {};
	const publicFlag = visibility?.public ?? postType?.public;
	const showUiFlag = visibility?.show_ui ?? postType?.show_ui;
	const excludeFromSearchFlag = visibility?.exclude_from_search ?? postType?.exclude_from_search;
	const showInNavMenusFlag = visibility?.show_in_nav_menus ?? postType?.show_in_nav_menus;

	return Boolean(
		postType?.slug &&
		publicFlag !== false &&
		showUiFlag === true &&
		excludeFromSearchFlag !== true &&
		showInNavMenusFlag === true
	);
}

const ALLOWED_INNER_BLOCKS = [
	'wlc-algolia/result-title',
	'wlc-algolia/result-image',
	'wlc-algolia/result-excerpt',
	'wlc-algolia/result-meta',
	'wlc-algolia/result-field',
	'wlc-algolia/result-button',
];

// Preset templates for autocomplete results (simpler than search page)
function presetTemplateByPostType( postType ) {
	const pt = String( postType || 'post' );
	if ( pt === 'product' ) {
		return [
			[ 'wlc-algolia/result-image', { fieldPath: 'images.thumbnail.url', linkType: 'permalink' } ],
			[ 'wlc-algolia/result-title', { fieldPath: 'post_title', linkType: 'permalink' } ],
			[ 'wlc-algolia/result-field', { label: 'Price', fieldPath: '_price' } ],
		];
	}
	// Generic template for posts/pages
	return [
		[ 'wlc-algolia/result-image', { fieldPath: 'images.thumbnail.url', linkType: 'permalink' } ],
		[ 'wlc-algolia/result-title', { fieldPath: 'post_title', linkType: 'permalink' } ],
		[ 'wlc-algolia/result-excerpt', { maxLength: 100 } ],
	];
}

function presetTemplateDefinitionsByPostType( postType ) {
	return presetTemplateByPostType( postType ).map( ( [ name, attrs ] ) => ( {
		name,
		attrs: attrs || {},
	} ) );
}

function serializeTemplateBlocks( blocks ) {
	if ( ! Array.isArray( blocks ) ) {
		return [];
	}
	return blocks
		.filter( ( block ) => block && ALLOWED_INNER_BLOCKS.includes( block.name ) )
		.map( ( block ) => ( {
			name: block.name,
			attrs: block.attributes || {},
		} ) );
}

function hydrateTemplateBlocks( templateDefinitions ) {
	if ( ! Array.isArray( templateDefinitions ) ) {
		return [];
	}
	return templateDefinitions
		.filter(
			( item ) =>
				item &&
				typeof item === 'object' &&
				ALLOWED_INNER_BLOCKS.includes( item.name )
		)
		.map( ( item ) => createBlock( item.name, item.attrs || {} ) );
}

export default function Edit( props ) {
	const { attributes, setAttributes, clientId } = props;
	const {
		querySuggestionsIndex,
		selectedPostTypes,
		templatesByPostType,
		maxSuggestions,
		maxResultsPerType,
		placeholder,
		showSuggestions,
		accentColor,
		resultLayout,
		resultLayoutColumns,
		searchPageUrl,
		showAllButtonLabel,
	} = attributes;
	const [ activeTemplatePostType, setActiveTemplatePostType ] = useState( '' );

	const postTypes = useSelect( ( select ) => {
		const data = select( 'core' ).getEntityRecords( 'root', 'postType', { per_page: -1 } );
		return data?.filter( isSearchableContentPostType );
	}, [] );

	const postTypeOptions = postTypes
		? postTypes.map( ( pt ) => ( { label: pt.labels?.singular_name || pt.slug, value: pt.slug } ) )
		: [];

	const innerCount = useSelect( ( s ) => {
		const block = s( 'core/block-editor' ).getBlock( clientId );
		return block?.innerBlocks?.length || 0;
	}, [ clientId ] );
	const innerBlocks = useSelect( ( s ) => {
		const block = s( 'core/block-editor' ).getBlock( clientId );
		return block?.innerBlocks || [];
	}, [ clientId ] );
	const selectedBlockClientId = useSelect(
		( s ) => s( 'core/block-editor' ).getSelectedBlockClientId(),
		[]
	);
	const templateUiBlocks = useMemo(
		() =>
			Array.isArray( innerBlocks )
				? innerBlocks.filter( ( block ) => block && block.clientId )
				: [],
		[ innerBlocks ]
	);

	const selectedTypesForTemplates =
		Array.isArray( selectedPostTypes ) && selectedPostTypes.length > 0
			? selectedPostTypes
			: [ 'post' ];
	const normalizedTemplatesByPostType =
		templatesByPostType && typeof templatesByPostType === 'object'
			? templatesByPostType
			: {};
	const activePostType = activeTemplatePostType || selectedTypesForTemplates[ 0 ];
	const activePostTypeOptions = selectedTypesForTemplates.map( ( postType ) => {
		const postTypeOption = postTypeOptions.find( ( option ) => option.value === postType );
		return {
			label: postTypeOption?.label || postType,
			value: postType,
		};
	} );
	const templateSections = useMemo(
		() =>
			selectedTypesForTemplates.map( ( postType ) => {
				const postTypeOption = postTypeOptions.find( ( option ) => option.value === postType );
				const definitions = Array.isArray( normalizedTemplatesByPostType[ postType ] )
					? normalizedTemplatesByPostType[ postType ]
					: presetTemplateDefinitionsByPostType( postType );
				return {
					postType,
					label: postTypeOption?.label || postType,
					definitions,
				};
			} ),
		[ selectedTypesForTemplates, postTypeOptions, normalizedTemplatesByPostType ]
	);
	const syncedTemplateRef = useRef( {} );
	const isApplyingTemplateRef = useRef( false );
	const pendingSelectRef = useRef( null );

	const updateActiveTemplateDefinitions = useCallback(
		( updater ) => {
			if ( ! activePostType ) {
				return;
			}
			const current = Array.isArray( normalizedTemplatesByPostType[ activePostType ] )
				? normalizedTemplatesByPostType[ activePostType ]
				: presetTemplateDefinitionsByPostType( activePostType );
			const next = updater( [ ...current ] );
			if ( ! Array.isArray( next ) ) {
				return;
			}
			setAttributes( {
				templatesByPostType: {
					...normalizedTemplatesByPostType,
					[ activePostType ]: next,
				},
			} );
		},
		[ activePostType, normalizedTemplatesByPostType, setAttributes ]
	);

	useEffect( () => {
		if ( ! activeTemplatePostType || selectedTypesForTemplates.includes( activeTemplatePostType ) ) {
			return;
		}
		setActiveTemplatePostType( selectedTypesForTemplates[ 0 ] );
	}, [ activeTemplatePostType, selectedTypesForTemplates ] );

	useEffect( () => {
		if ( activeTemplatePostType ) {
			return;
		}
		setActiveTemplatePostType( selectedTypesForTemplates[ 0 ] );
	}, [ activeTemplatePostType, selectedTypesForTemplates ] );

	useEffect( () => {
		const nextTemplates = { ...normalizedTemplatesByPostType };
		let hasChanges = false;
		selectedTypesForTemplates.forEach( ( postType, idx ) => {
			if ( Array.isArray( nextTemplates[ postType ] ) && nextTemplates[ postType ].length > 0 ) {
				return;
			}
			if ( idx === 0 && Object.keys( nextTemplates ).length === 0 && innerCount > 0 ) {
				nextTemplates[ postType ] = serializeTemplateBlocks( innerBlocks );
			} else {
				nextTemplates[ postType ] = presetTemplateDefinitionsByPostType( postType );
			}
			hasChanges = true;
		} );
		if ( hasChanges ) {
			setAttributes( { templatesByPostType: nextTemplates } );
		}
	}, [ normalizedTemplatesByPostType, selectedTypesForTemplates, innerCount, innerBlocks, setAttributes ] );

	useEffect( () => {
		if ( ! activePostType ) {
			return;
		}
		const templateDefinitions = Array.isArray( normalizedTemplatesByPostType[ activePostType ] )
			? normalizedTemplatesByPostType[ activePostType ]
			: presetTemplateDefinitionsByPostType( activePostType );
		const nextBlocks = hydrateTemplateBlocks( templateDefinitions );
		const nextSerialized = JSON.stringify( serializeTemplateBlocks( nextBlocks ) );
		const currentSerialized = JSON.stringify( serializeTemplateBlocks( innerBlocks ) );
		if ( nextSerialized === currentSerialized ) {
			return;
		}
		isApplyingTemplateRef.current = true;
		const blockEditorDispatch = dispatch( 'core/block-editor' );
		if ( typeof blockEditorDispatch.replaceInnerBlocks === 'function' ) {
			blockEditorDispatch.replaceInnerBlocks( clientId, nextBlocks, false );
			return;
		}
		const existingBlockClientIds = ( innerBlocks || [] )
			.filter( ( block ) => block && block.clientId )
			.map( ( block ) => block.clientId );
		if ( existingBlockClientIds.length ) {
			blockEditorDispatch.removeBlocks( existingBlockClientIds, false );
		}
		blockEditorDispatch.insertBlocks( nextBlocks, 0, clientId );
	}, [ activePostType, normalizedTemplatesByPostType, innerBlocks, clientId ] );

	useEffect( () => {
		if ( ! activePostType ) {
			return;
		}
		if ( isApplyingTemplateRef.current ) {
			isApplyingTemplateRef.current = false;
			return;
		}
		const serialized = serializeTemplateBlocks( innerBlocks );
		const serializedKey = JSON.stringify( serialized );
		if ( syncedTemplateRef.current[ activePostType ] === serializedKey ) {
			return;
		}
		const existingSerialized = JSON.stringify(
			Array.isArray( normalizedTemplatesByPostType[ activePostType ] )
				? normalizedTemplatesByPostType[ activePostType ]
				: []
		);
		syncedTemplateRef.current[ activePostType ] = serializedKey;
		if ( existingSerialized === serializedKey ) {
			return;
		}
		setAttributes( {
			templatesByPostType: {
				...normalizedTemplatesByPostType,
				[ activePostType ]: serialized,
			},
		} );
	}, [ activePostType, innerBlocks, normalizedTemplatesByPostType, setAttributes ] );

	useEffect( () => {
		if (
			! pendingSelectRef.current ||
			pendingSelectRef.current.postType !== activePostType
		) {
			return;
		}
		const targetIndex = pendingSelectRef.current.index;
		const targetClientId = templateUiBlocks[ targetIndex ]?.clientId;
		if ( targetClientId ) {
			dispatch( 'core/block-editor' ).selectBlock( targetClientId );
			pendingSelectRef.current = null;
		}
	}, [ activePostType, templateUiBlocks ] );

	// Keep image block first to match Search Page template behavior.
	useEffect( () => {
		const safeBlocks = Array.isArray( innerBlocks )
			? innerBlocks.filter( ( block ) => block && block.clientId )
			: [];
		if ( safeBlocks.length < 2 ) return;
		const imageIndex = safeBlocks.findIndex( ( block ) => block?.name === 'wlc-algolia/result-image' );
		if ( imageIndex <= 0 ) return;
		const imageBlockClientId = safeBlocks[ imageIndex ]?.clientId;
		if ( ! imageBlockClientId ) return;
		dispatch( 'core/block-editor' ).moveBlocksToPosition( [ imageBlockClientId ], clientId, clientId, 0 );
	}, [ innerBlocks, clientId ] );

	// Fields/key management for quick insertion
	const [ keysLoading, setKeysLoading ] = useState( false );
	const [ keysError, setKeysError ] = useState( '' );
	const [ keysQuery, setKeysQuery ] = useState( '' );
	const [ availableKeys, setAvailableKeys ] = useState( [] );
	const keysQueryRef = useRef( keysQuery );

	// Load available index keys for the active template post type.
	useEffect( () => {
		let cancelled = false;
		async function loadKeys() {
			setKeysLoading( true );
			setKeysError( '' );
			try {
				const data = await apiFetch( {
					path: `/wlc-algolia/v1/index-keys/?post_type=${ encodeURIComponent( activePostType || 'post' ) }`,
				} );
				if ( cancelled ) return;
				const keys = Array.isArray( data?.keys ) ? data.keys : [];
				setAvailableKeys( keys );
			} catch ( e ) {
				if ( cancelled ) return;
				setAvailableKeys( [] );
				setKeysError( e?.message || 'Failed to load keys.' );
			} finally {
				if ( ! cancelled ) setKeysLoading( false );
			}
		}
		loadKeys();
		return () => {
			cancelled = true;
		};
	}, [ activePostType ] );

	// Reset search query when post type changes
	useEffect( () => {
		keysQueryRef.current = '';
		setKeysQuery( '' );
	}, [ activePostType ] );

	// Filter keys by query
	const filteredKeys = useMemo( () => {
		const q = String( keysQuery || '' ).toLowerCase().trim();
		if ( ! q ) return availableKeys.slice( 0, 100 );
		return availableKeys.filter( ( k ) => String( k?.path || '' ).toLowerCase().includes( q ) ).slice( 0, 150 );
	}, [ availableKeys, keysQuery ] );

	const handleKeysQueryChange = useCallback( ( value ) => {
		const newValue = value || '';
		keysQueryRef.current = newValue;
		setKeysQuery( newValue );
	}, [] );

	// Insert field block helper
	function insertFieldBlock( path ) {
		const p = String( path || '' ).trim();
		if ( ! p ) return;
		const label = p.split( '.' ).slice( -1 )[0] || p;
		updateActiveTemplateDefinitions( ( next ) => {
			next.push( {
				name: 'wlc-algolia/result-field',
				attrs: { fieldPath: p, label },
			} );
			return next;
		} );
	}

	function removeTemplateBlockAtIndex( index ) {
		updateActiveTemplateDefinitions( ( next ) => {
			if ( index < 0 || index >= next.length ) {
				return next;
			}
			next.splice( index, 1 );
			return next;
		} );
	}

	function moveTemplateBlockAtIndex( index, direction ) {
		updateActiveTemplateDefinitions( ( next ) => {
			if ( index < 0 || index >= next.length ) {
				return next;
			}
			const fromBlock = next[ index ];
			if ( fromBlock?.name === 'wlc-algolia/result-image' ) {
				return next;
			}
			const toIndex = direction === 'up' ? index - 1 : index + 1;
			if ( toIndex < 0 || toIndex >= next.length ) {
				return next;
			}
			const targetBlock = next[ toIndex ];
			if ( targetBlock?.name === 'wlc-algolia/result-image' ) {
				return next;
			}
			[ next[ index ], next[ toIndex ] ] = [ next[ toIndex ], next[ index ] ];
			return next;
		} );
	}

	function handleTemplateItemClick( postType, index ) {
		if ( postType !== activePostType ) {
			pendingSelectRef.current = { postType, index };
			setActiveTemplatePostType( postType );
			return;
		}
		const targetClientId = templateUiBlocks[ index ]?.clientId;
		if ( targetClientId ) {
			dispatch( 'core/block-editor' ).selectBlock( targetClientId );
		}
	}

	function getTemplateBlockTitle( block ) {
		if ( ! block?.name ) return __( 'Block', 'wlc-search-integration-with-algolia' );
		const blockName = String( block.name );
		if ( blockName === 'wlc-algolia/result-title' ) return __( 'Title', 'wlc-search-integration-with-algolia' );
		if ( blockName === 'wlc-algolia/result-image' ) return __( 'Image', 'wlc-search-integration-with-algolia' );
		if ( blockName === 'wlc-algolia/result-excerpt' ) return __( 'Excerpt', 'wlc-search-integration-with-algolia' );
		if ( blockName === 'wlc-algolia/result-meta' ) return __( 'Meta', 'wlc-search-integration-with-algolia' );
		if ( blockName === 'wlc-algolia/result-field' ) return __( 'Field', 'wlc-search-integration-with-algolia' );
		if ( blockName === 'wlc-algolia/result-button' ) return __( 'Button', 'wlc-search-integration-with-algolia' );
		return blockName.replace( /^wlc-algolia\//, '' );
	}

	function getTemplateBlockMeta( block ) {
		if ( ! block?.attributes ) return '';
		if ( block.name === 'wlc-algolia/result-field' ) {
			return block.attributes.fieldPath || '';
		}
		if ( block.name === 'wlc-algolia/result-title' ) {
			return block.attributes.fieldPath || 'post_title';
		}
		if ( block.name === 'wlc-algolia/result-image' ) {
			return block.attributes.fieldPath || 'images.thumbnail.url';
		}
		if ( block.name === 'wlc-algolia/result-button' ) {
			return block.attributes.label || '';
		}
		return '';
	}

	const [ availableIndexes, setAvailableIndexes ] = useState( [] );
	const [ algoliaIndices, setAlgoliaIndices ] = useState( [] );

	// CPT-based indices (for post type results).
	useEffect( () => {
		async function loadIndexes() {
			try {
				const data = await apiFetch( {
					path: '/wlc-algolia/v1/autocomplete-settings/',
				} );
				if ( data?.autocomplete_settings ) {
					const indexes = [];
					Object.values( data.autocomplete_settings ).forEach( ( item ) => {
						if ( item?.index_name ) {
							indexes.push( {
								label: item.index_name,
								value: item.index_name,
							} );
						}
					} );
					setAvailableIndexes( indexes );
				}
			} catch ( e ) {
				console.error( 'Failed to load indexes:', e );
			}
		}
		loadIndexes();
	}, [] );

	// All Algolia indices (for Query Suggestions index – includes query suggestions index).
	useEffect( () => {
		async function loadAlgoliaIndices() {
			try {
				const data = await apiFetch( {
					path: '/wlc-algolia/v1/indices/',
				} );
				if ( data?.indices && Array.isArray( data.indices ) ) {
					const options = data.indices
						.map( ( item ) => ( { label: item.name, value: item.name } ) )
						.sort( ( a, b ) => a.label.localeCompare( b.label ) );
					setAlgoliaIndices( options );
				}
			} catch ( e ) {
				console.error( 'Failed to load Algolia indices:', e );
			}
		}
		loadAlgoliaIndices();
	}, [] );

	function togglePostType( postType, enabled ) {
		const next = Array.isArray( selectedPostTypes ) ? [ ...selectedPostTypes ] : [];
		const idx = next.indexOf( postType );
		if ( enabled && idx === -1 ) {
			next.push( postType );
		} else if ( ! enabled && idx !== -1 ) {
			next.splice( idx, 1 );
		}
		const nextTemplates = { ...normalizedTemplatesByPostType };
		if ( enabled ) {
			if ( ! Array.isArray( nextTemplates[ postType ] ) || nextTemplates[ postType ].length === 0 ) {
				nextTemplates[ postType ] = presetTemplateDefinitionsByPostType( postType );
			}
			setActiveTemplatePostType( postType );
		} else {
			delete nextTemplates[ postType ];
			if ( activePostType === postType ) {
				setActiveTemplatePostType( next[ 0 ] || 'post' );
			}
		}
		setAttributes( {
			selectedPostTypes: next,
			templatesByPostType: nextTemplates,
		} );
	}

	return (
		<>
			<InspectorControls>
				<PanelBody title={ __( 'Search & results', 'wlc-search-integration-with-algolia' ) } initialOpen={ true }>
					<div style={ { marginBottom: 8, fontWeight: 600 } }>
						{ __( 'Post types', 'wlc-search-integration-with-algolia' ) }
					</div>
					{ postTypeOptions.map( ( pt ) => {
						const checked = Array.isArray( selectedPostTypes ) ? selectedPostTypes.includes( pt.value ) : false;
						return (
							<ToggleControl
								key={ pt.value }
								label={ pt.label }
								checked={ checked }
								onChange={ ( v ) => togglePostType( pt.value, v ) }
							/>
						);
					} ) }
					<RangeControl
						label={ __( 'Max hits per post type', 'wlc-search-integration-with-algolia' ) }
						help={ __( 'How many records to show for each selected post type while typing.', 'wlc-search-integration-with-algolia' ) }
						min={ 1 }
						max={ 10 }
						value={ maxResultsPerType }
						onChange={ ( v ) => setAttributes( { maxResultsPerType: v || 3 } ) }
					/>
					<TextControl
						label={ __( 'Placeholder', 'wlc-search-integration-with-algolia' ) }
						value={ placeholder }
						onChange={ ( v ) => setAttributes( { placeholder: v } ) }
					/>
					<div style={ { marginTop: 12 } }>
						<div style={ { marginBottom: 8, fontWeight: 600 } }>{ __( 'Accent color', 'wlc-search-integration-with-algolia' ) }</div>
						<ColorPalette
							value={ accentColor }
							onChange={ ( v ) => setAttributes( { accentColor: v || '#DB002F' } ) }
						/>
					</div>
				</PanelBody>

				<PanelBody title={ __( 'Popular searches', 'wlc-search-integration-with-algolia' ) } initialOpen={ false }>
					<ToggleControl
						label={ __( 'Show popular searches', 'wlc-search-integration-with-algolia' ) }
						help={ __( 'Shows suggested queries or titles alongside your result hits. Turn off if you only want indexed results.', 'wlc-search-integration-with-algolia' ) }
						checked={ showSuggestions !== false }
						onChange={ ( v ) => setAttributes( { showSuggestions: !! v } ) }
					/>
					<SelectControl
						label={ __( 'Popular searches index', 'wlc-search-integration-with-algolia' ) }
						help={ __(
							'Recommended: your Algolia Query Suggestions index. You may pick any index—titles or query fields are shown as clickable suggestions.',
							'wlc-search-integration-with-algolia'
						) }
						value={ querySuggestionsIndex }
						options={ [
							{ label: __( 'None', 'wlc-search-integration-with-algolia' ), value: '' },
							...algoliaIndices,
						] }
						onChange={ ( v ) => setAttributes( { querySuggestionsIndex: v } ) }
					/>
					<RangeControl
						label={ __( 'Max popular search items', 'wlc-search-integration-with-algolia' ) }
						help={ __( 'Algolia hitsPerPage for the popular searches index only—not the same as max hits per post type.', 'wlc-search-integration-with-algolia' ) }
						min={ 1 }
						max={ 20 }
						value={ maxSuggestions }
						onChange={ ( v ) => setAttributes( { maxSuggestions: v || 5 } ) }
					/>
				</PanelBody>

				<PanelBody title={ __( 'Search Page Link', 'wlc-search-integration-with-algolia' ) } initialOpen={ false }>
					<TextControl
						label={ __( 'Search Page URL', 'wlc-search-integration-with-algolia' ) }
						value={ searchPageUrl || '' }
						onChange={ ( v ) => setAttributes( { searchPageUrl: v || '' } ) }
						help={ __( 'URL to the search results page. Query parameter will be added automatically (e.g., ?s=query).', 'wlc-search-integration-with-algolia' ) }
					/>
					<TextControl
						label={ __( 'Show All Button Label', 'wlc-search-integration-with-algolia' ) }
						value={ showAllButtonLabel || 'Show all' }
						onChange={ ( v ) => setAttributes( { showAllButtonLabel: v || 'Show all' } ) }
						help={ __( 'Label for the "Show all" button in autocomplete results.', 'wlc-search-integration-with-algolia' ) }
					/>
				</PanelBody>

				<PanelBody title={ __( 'Result Layout', 'wlc-search-integration-with-algolia' ) } initialOpen={ false }>
					<SelectControl
						label={ __( 'Layout', 'wlc-search-integration-with-algolia' ) }
						value={ resultLayout }
						options={ [
							{ label: __( 'Vertical (Stacked)', 'wlc-search-integration-with-algolia' ), value: 'vertical' },
							{ label: __( 'Grid', 'wlc-search-integration-with-algolia' ), value: 'grid' },
						] }
						onChange={ ( v ) => setAttributes( { resultLayout: v || 'vertical' } ) }
					/>
					{ resultLayout === 'grid' && (
						<RangeControl
							label={ __( 'Columns', 'wlc-search-integration-with-algolia' ) }
							min={ 2 }
							max={ 4 }
							value={ resultLayoutColumns }
							onChange={ ( v ) => setAttributes( { resultLayoutColumns: v || 2 } ) }
						/>
					) }
				</PanelBody>
			</InspectorControls>

			<div { ...useBlockProps() }>
				<div className="wp-block-wlc-algolia-autocomplete__editor">
					<div className="wp-block-wlc-algolia-autocomplete__editor-header">
						<div className="wp-block-wlc-algolia-autocomplete__editor-header-top">
							<h3>{ __( 'Algolia Autocomplete', 'wlc-search-integration-with-algolia' ) }</h3>
							{ activePostTypeOptions.length > 1 && (
								<div className="wp-block-wlc-algolia-autocomplete__template-switch">
									<SelectControl
										label={ __( 'Template post type', 'wlc-search-integration-with-algolia' ) }
										value={ activePostType }
										options={ activePostTypeOptions }
										onChange={ ( value ) => setActiveTemplatePostType( value ) }
										help={ __( 'Changing this switches fields and template blocks.', 'wlc-search-integration-with-algolia' ) }
									/>
								</div>
							) }
						</div>
						<div className="wp-block-wlc-algolia-autocomplete__editor-preview">
							<input
								type="search"
								placeholder={ placeholder || __( 'Search...', 'wlc-search-integration-with-algolia' ) }
								disabled
								style={ {
									width: '100%',
									padding: '12px',
									border: '1px solid #ddd',
									borderRadius: '8px',
									fontSize: 16,
								} }
							/>
						</div>
					</div>

					<div className="wp-block-wlc-algolia-search-page-v2__editor-layout">
						<div className="wp-block-wlc-algolia-search-page-v2__editor-panel">
							<h4 className="wp-block-wlc-algolia-search-page-v2__editor-panel-title">
								{ __( 'Available Fields', 'wlc-search-integration-with-algolia' ) }
							</h4>
							<div className="wp-block-wlc-algolia-search-page-v2__editor-search">
								<input
									type="search"
									className="wp-block-wlc-algolia-search-page-v2__editor-search-input"
									placeholder={ __( 'Search fields…', 'wlc-search-integration-with-algolia' ) }
									value={ String( keysQuery || '' ) }
									onChange={ ( e ) => handleKeysQueryChange( e.target.value ) }
								/>
							</div>
							{ keysError && (
								<Notice status="error" isDismissible={ false }>
									{ keysError }
								</Notice>
							) }
							<div className="wp-block-wlc-algolia-search-page-v2__editor-hint">
								{ keysLoading
									? __( 'Loading fields…', 'wlc-search-integration-with-algolia' )
									: __( 'Click "Add" to insert a Result Field block into your template.', 'wlc-search-integration-with-algolia' ) }
							</div>
							<div className="wp-block-wlc-algolia-search-page-v2__editor-field-list">
								{ filteredKeys.map( ( key ) => (
									<div key={ key.path } className="wp-block-wlc-algolia-search-page-v2__editor-field-item">
										<div className="wp-block-wlc-algolia-search-page-v2__editor-field-info">
											<div className="wp-block-wlc-algolia-search-page-v2__editor-field-path">{ key.path }</div>
										</div>
										<Button variant="secondary" isSmall onClick={ () => insertFieldBlock( key.path ) }>
											{ __( 'Add', 'wlc-search-integration-with-algolia' ) }
										</Button>
									</div>
								) ) }
							</div>
						</div>

						<div className="wp-block-wlc-algolia-search-page-v2__editor-panel">
							<h4 className="wp-block-wlc-algolia-search-page-v2__editor-panel-title">
								{ __( 'Template Blocks', 'wlc-search-integration-with-algolia' ) }
							</h4>
							<div className="wp-block-wlc-algolia-search-page-v2__editor-hint">
								{ __( 'Editing template for:', 'wlc-search-integration-with-algolia' ) } <strong>{ activePostType }</strong>
							</div>
							<div className="wp-block-wlc-algolia-search-page-v2__editor-hint">
								{ __( 'Click a block to open its settings. Use arrows to reorder or remove.', 'wlc-search-integration-with-algolia' ) }
							</div>
							{ templateSections.map( ( section ) => {
								const isActiveSection = section.postType === activePostType;
								const sectionBlocks = isActiveSection ? templateUiBlocks : section.definitions;
								return (
									<div key={ section.postType } className="wp-block-wlc-algolia-search-page-v2__editor-template-list">
										<div className="wp-block-wlc-algolia-search-page-v2__editor-hint">
											<strong>{ section.label }</strong>
											{ isActiveSection ? '' : ` (${ __( 'click to edit', 'wlc-search-integration-with-algolia' ) })` }
										</div>
										{ sectionBlocks.map( ( block, index ) => {
											const blockClientId = isActiveSection ? block?.clientId : '';
											const isSelected = isActiveSection && blockClientId && selectedBlockClientId === blockClientId;
											return (
												<div
													key={ `${ section.postType }-${ block?.name || 'block' }-${ index }` }
													className={ `wp-block-wlc-algolia-search-page-v2__editor-template-item ${ isSelected ? 'is-selected' : '' }` }
													role="button"
													tabIndex={ 0 }
													onClick={ () => handleTemplateItemClick( section.postType, index ) }
													onKeyDown={ ( event ) => {
														if ( event.key === 'Enter' || event.key === ' ' ) {
															event.preventDefault();
															handleTemplateItemClick( section.postType, index );
														}
													} }
												>
													<div className="wp-block-wlc-algolia-search-page-v2__editor-template-item-info">
														<div className="wp-block-wlc-algolia-search-page-v2__editor-template-item-title">
															{ index + 1 }. { getTemplateBlockTitle( block ) }
														</div>
														{ !! getTemplateBlockMeta( block ) && (
															<div className="wp-block-wlc-algolia-search-page-v2__editor-template-item-meta">
																{ getTemplateBlockMeta( block ) }
															</div>
														) }
													</div>
													{ isActiveSection && (
														<div className="wp-block-wlc-algolia-search-page-v2__editor-template-item-actions">
															<Button
																variant="secondary"
																isSmall
																disabled={ index === 0 || block?.name === 'wlc-algolia/result-image' }
																onClick={ ( event ) => {
																	event.stopPropagation();
																	moveTemplateBlockAtIndex( index, 'up' );
																} }
															>
																{ __( 'Up', 'wlc-search-integration-with-algolia' ) }
															</Button>
															<Button
																variant="secondary"
																isSmall
																disabled={ index === sectionBlocks.length - 1 || block?.name === 'wlc-algolia/result-image' }
																onClick={ ( event ) => {
																	event.stopPropagation();
																	moveTemplateBlockAtIndex( index, 'down' );
																} }
															>
																{ __( 'Down', 'wlc-search-integration-with-algolia' ) }
															</Button>
															<Button
																variant="tertiary"
																isDestructive
																isSmall
																onClick={ ( event ) => {
																	event.stopPropagation();
																	removeTemplateBlockAtIndex( index );
																} }
															>
																{ __( 'Remove', 'wlc-search-integration-with-algolia' ) }
															</Button>
														</div>
													) }
												</div>
											);
										} ) }
									</div>
								);
							} ) }

							<div className="wp-block-wlc-algolia-autocomplete__editor-template-blocks">
								<InnerBlocks
									allowedBlocks={ ALLOWED_INNER_BLOCKS }
									orientation="vertical"
									renderAppender={ InnerBlocks.ButtonBlockAppender }
								/>
							</div>
						</div>
					</div>
				</div>
			</div>
		</>
	);
}
