/**
 * Editor-side registration for the six Phase 5 server-rendered blocks.
 *
 * No build step — uses the WP runtime globals (wp.blocks, wp.element,
 * wp.serverSideRender, wp.blockEditor, wp.components, wp.i18n, wp.data).
 * Each block is registered with:
 *
 *   • title / icon / category / keywords (mirrors block.json)
 *   • attributes pulled from a small whitelist below
 *   • edit() that renders <ServerSideRender> inside the editor canvas with
 *     an InspectorControls sidebar for the inserter-set attributes
 *   • save() returns null (dynamic block — render is server-side only)
 *
 * Why this file exists: WordPress only knows about blocks the editor's JS
 * has registered. PHP-side `register_block_type()` covers the *rendering*
 * pipeline, but if no JS-side registration exists the editor shows
 * "Your site doesn't include support for the X block" when a saved post
 * contains the block markup. <ServerSideRender> bridges that gap so the
 * editor preview matches the frontend output.
 */
( function ( wp ) {
	if ( ! wp || ! wp.blocks ) {
		return;
	}

	var el                = wp.element.createElement;
	var Fragment          = wp.element.Fragment;
	var useState          = wp.element.useState;
	var useEffect         = wp.element.useEffect;
	var registerBlockType = wp.blocks.registerBlockType;
	var ServerSideRender  = wp.serverSideRender;
	var __                = wp.i18n.__;
	var apiFetch          = wp.apiFetch;
	// `addQueryArgs` is essential when REST URLs use `?rest_route=` — it
	// uses `&` as the separator instead of a second `?` that would break
	// query parsing. With pretty permalinks the result is identical.
	var addQueryArgs      = wp.url && wp.url.addQueryArgs ? wp.url.addQueryArgs : function ( path, args ) {
		var q = Object.keys( args || {} )
			.filter( function ( k ) { return args[ k ] !== '' && args[ k ] !== undefined && args[ k ] !== null; } )
			.map( function ( k ) { return encodeURIComponent( k ) + '=' + encodeURIComponent( args[ k ] ); } )
			.join( '&' );
		if ( ! q ) {
			return path;
		}
		return path + ( path.indexOf( '?' ) === -1 ? '?' : '&' ) + q;
	};

	var InspectorControls = wp.blockEditor && wp.blockEditor.InspectorControls;
	var useBlockProps     = wp.blockEditor && wp.blockEditor.useBlockProps;

	var PanelBody       = wp.components && wp.components.PanelBody;
	var TextControl     = wp.components && wp.components.TextControl;
	var SelectControl   = wp.components && wp.components.SelectControl;
	var ToggleControl   = wp.components && wp.components.ToggleControl;
	var RangeControl    = wp.components && wp.components.RangeControl;
	var ComboboxControl = wp.components && wp.components.ComboboxControl;
	var Spinner         = wp.components && wp.components.Spinner;

	// ----- Cached fetch for taxonomy options -----
	// /search-options returns all makes, body_styles, conditions etc. in a
	// single response, so we fetch it once per editor session and reuse.
	var _searchOptionsPromise = null;
	function getSearchOptions() {
		if ( ! _searchOptionsPromise ) {
			_searchOptionsPromise = apiFetch( {
				path: '/trx-auto-dealer/v1/search-options',
			} ).catch( function () { return {}; } );
		}
		return _searchOptionsPromise;
	}

	// Build {value, label} options for a taxonomy slug (e.g. 'makes',
	// 'body_styles'). Returns an empty array until fetch resolves.
	function useTermOptions( taxKey ) {
		var state    = useState( null );
		var options  = state[0];
		var setOpts  = state[1];
		useEffect( function () {
			var cancelled = false;
			getSearchOptions().then( function ( data ) {
				if ( cancelled ) {
					return;
				}
				var list = ( data && data[ taxKey ] ) || [];
				setOpts( [ { value: '', label: __( 'Any', 'trx-auto-dealer' ) } ].concat(
					list.map( function ( t ) {
						return { value: t.slug, label: t.name + ' (' + t.count + ')' };
					} )
				) );
			} );
			return function () { cancelled = true; };
		}, [ taxKey ] );
		return options || [ { value: '', label: __( 'Loading…', 'trx-auto-dealer' ) } ];
	}

	// ----- Searchable post picker (vehicles / dealers) -----
	// Renders a ComboboxControl with debounced REST search. The current
	// value (an integer ID) is stored as the attribute; the human-readable
	// label is fetched separately so the dropdown shows the right title
	// when the inspector first loads.
	function PostPicker( props ) {
		var endpoint    = props.endpoint;       // e.g. 'vehicles', 'dealers'
		var labelField  = props.labelField;     // 'title' for vehicles, 'name' for dealers
		var label       = props.label;
		var currentId   = parseInt( props.value, 10 ) || 0;
		var onChange    = props.onChange;

		var state1   = useState( '' );
		var query    = state1[0];
		var setQuery = state1[1];
		var state2   = useState( [] );
		var results  = state2[0];
		var setResults = state2[1];
		var state3   = useState( false );
		var loading  = state3[0];
		var setLoading = state3[1];
		var state4   = useState( '' );
		var currentLabel = state4[0];
		var setCurrentLabel = state4[1];

		// Fetch the current ID's title so we can display the selected item.
		useEffect( function () {
			if ( currentId <= 0 ) {
				setCurrentLabel( '' );
				return;
			}
			var cancelled = false;
			apiFetch( {
				path: '/trx-auto-dealer/v1/' + endpoint + '/' + currentId,
			} ).then( function ( data ) {
				if ( ! cancelled && data && data[ labelField ] ) {
					setCurrentLabel( data[ labelField ] );
				}
			} ).catch( function () {} );
			return function () { cancelled = true; };
		}, [ currentId, endpoint, labelField ] );

		// Debounced search. Empty query is a valid request — it returns the
		// most recent N items, so the dropdown is browseable without typing.
		// Debounce only kicks in for non-empty queries; the initial load
		// (query === '') fires immediately on mount.
		useEffect( function () {
			setLoading( true );
			var cancelled = false;
			var delay     = query ? 250 : 0;
			var t = setTimeout( function () {
				apiFetch( {
					path: addQueryArgs( '/trx-auto-dealer/v1/' + endpoint, { search: query, per_page: 20 } ),
				} ).then( function ( data ) {
					if ( cancelled ) {
						return;
					}
					setResults( Array.isArray( data ) ? data : [] );
					setLoading( false );
				} ).catch( function () {
					if ( ! cancelled ) {
						setResults( [] );
						setLoading( false );
					}
				} );
			}, delay );
			return function () { cancelled = true; clearTimeout( t ); };
		}, [ query, endpoint ] );

		// Build options: include the current selection at the top so it
		// stays visible even when the search query doesn't match it.
		var options = [];
		if ( currentId > 0 ) {
			options.push( {
				value: String( currentId ),
				label: '#' + currentId + ( currentLabel ? ' — ' + currentLabel : ' — ' + __( '(loading…)', 'trx-auto-dealer' ) ),
			} );
		}
		options.push( { value: '0', label: __( '— None (use post context) —', 'trx-auto-dealer' ) } );
		results.forEach( function ( item ) {
			if ( item.id === currentId ) {
				return; // already at top
			}
			options.push( {
				value: String( item.id ),
				label: '#' + item.id + ' — ' + ( item[ labelField ] || '(no title)' ),
			} );
		} );

		if ( ComboboxControl ) {
			return el( ComboboxControl, {
				label:               label,
				value:               String( currentId ),
				options:             options,
				onChange:            function ( v ) { onChange( parseInt( v, 10 ) || 0 ); },
				onFilterValueChange: function ( q ) { setQuery( q ); },
				help:                loading ? __( 'Searching…', 'trx-auto-dealer' ) : __( 'Type to search', 'trx-auto-dealer' ),
				allowReset:          false,
			} );
		}

		// Fallback when ComboboxControl isn't available (very old WP).
		return el( SelectControl, {
			label:    label,
			value:    String( currentId ),
			options:  options,
			onChange: function ( v ) { onChange( parseInt( v, 10 ) || 0 ); },
		} );
	}

	// Synchronous taxonomy dropdown — uses the cached /search-options.
	function TermSelect( props ) {
		var options = useTermOptions( props.taxonomy );
		return el( SelectControl, {
			label:    props.label,
			value:    props.value || '',
			options:  options,
			onChange: props.onChange,
		} );
	}

	/**
	 * Build a generic edit() that renders ServerSideRender + an Inspector
	 * panel with whatever controls the block defines.
	 *
	 * @param {string} blockName
	 * @param {Array}  controls — each: { type, attr, label, options?, min?, max? }
	 */
	function makeEdit( blockName, controls ) {
		return function ( props ) {
			var attrs    = props.attributes || {};
			var setAttrs = props.setAttributes;
			var blockProps = useBlockProps ? useBlockProps() : {};

			var inspector = null;
			if ( InspectorControls && PanelBody && controls && controls.length ) {
				var children = controls.map( function ( c ) {
					// Section-divider heading inside the panel — non-interactive.
					if ( c.type === 'heading' ) {
						return el( 'h3', { style: { fontSize: '11px', textTransform: 'uppercase', letterSpacing: '0.04em', margin: '16px 0 8px', color: '#1e1e1e', borderTop: '1px solid #ddd', paddingTop: '12px' } }, c.label );
					}
					var common = {
						label: c.label,
						value: attrs[ c.attr ] !== undefined ? attrs[ c.attr ] : ( c.defaultValue !== undefined ? c.defaultValue : '' ),
						onChange: function ( v ) {
							var update = {};
							update[ c.attr ] = v;
							setAttrs( update );
						},
					};
					if ( c.type === 'select' && SelectControl ) {
						common.options = c.options || [];
						return el( SelectControl, common );
					}
					if ( c.type === 'vehiclePicker' ) {
						return el( PostPicker, {
							endpoint:   'vehicles',
							labelField: 'title',
							label:      c.label,
							value:      attrs[ c.attr ],
							onChange:   function ( v ) {
								var update = {};
								update[ c.attr ] = v;
								setAttrs( update );
							},
						} );
					}
					if ( c.type === 'dealerPicker' ) {
						return el( PostPicker, {
							endpoint:   'dealers',
							labelField: 'name',
							label:      c.label,
							value:      attrs[ c.attr ],
							onChange:   function ( v ) {
								var update = {};
								update[ c.attr ] = v;
								setAttrs( update );
							},
						} );
					}
					if ( c.type === 'termPicker' ) {
						// `c.taxonomy` is the search-options key: 'makes',
						// 'body_styles', 'fuel_types', 'conditions'.
						return el( TermSelect, {
							taxonomy: c.taxonomy,
							label:    c.label,
							value:    attrs[ c.attr ],
							onChange: function ( v ) {
								var update = {};
								update[ c.attr ] = v;
								setAttrs( update );
							},
						} );
					}
					if ( c.type === 'toggle' && ToggleControl ) {
						common.checked = !! attrs[ c.attr ];
						delete common.value;
						return el( ToggleControl, common );
					}
					if ( c.type === 'multiToggle' && ToggleControl ) {
						// `c.attr` holds an array of selected option `value`s.
						// Each option becomes a ToggleControl that pushes/
						// splices its value in the array on change.
						var current = Array.isArray( attrs[ c.attr ] ) ? attrs[ c.attr ].slice() : [];
						return el(
							'div',
							{ style: { display: 'flex', flexDirection: 'column', gap: '4px' } },
							( c.options || [] ).map( function ( opt ) {
								return el( ToggleControl, {
									key:     opt.value,
									label:   opt.label,
									checked: current.indexOf( opt.value ) !== -1,
									onChange: function ( on ) {
										var next = current.slice();
										var idx  = next.indexOf( opt.value );
										if ( on && idx === -1 ) { next.push( opt.value ); }
										if ( ! on && idx !== -1 ) { next.splice( idx, 1 ); }
										var update = {};
										update[ c.attr ] = next;
										setAttrs( update );
										current = next;
									},
								} );
							} )
						);
					}
					if ( c.type === 'range' && RangeControl ) {
						common.min = c.min;
						common.max = c.max;
						return el( RangeControl, common );
					}
					if ( c.type === 'number' && TextControl ) {
						common.type = 'number';
						return el( TextControl, common );
					}
					return el( TextControl, common );
				} );
				inspector = el(
					InspectorControls,
					null,
					el( PanelBody, { title: __( 'Block Settings', 'trx-auto-dealer' ), initialOpen: true }, children )
				);
			}

			var preview = el(
				'div',
				blockProps,
				el( ServerSideRender, {
					block:                  blockName,
					attributes:             attrs,
					EmptyResponsePlaceholder: function () {
						return el(
							'div',
							{ style: { padding: '1rem', background: '#f4f5f7', border: '1px dashed #c3c4c7', borderRadius: '4px', textAlign: 'center', color: '#646970' } },
							__( 'No preview available — saved post will render this block on the front end.', 'trx-auto-dealer' )
						);
					},
				} )
			);

			return el( Fragment, null, inspector, preview );
		};
	}

	function dynamicSave() {
		return null;
	}

	// ----- search-form -----
	registerBlockType( 'trx-auto-dealer/search-form', {
		title:       __( 'Vehicle Search Form', 'trx-auto-dealer' ),
		description: __( 'Filter form: keyword, make, model, body style, year, price, mileage and more.', 'trx-auto-dealer' ),
		icon:        'search',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'search', 'trx-auto-dealer' ), __( 'filter', 'trx-auto-dealer' ), __( 'vehicle', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide', 'full' ] },
		attributes:  {
			action:           { type: 'string',  default: '' },
			heading:          { type: 'string',  default: '' },
			submitLabel:      { type: 'string',  default: '' },
			compact:          { type: 'boolean', default: false },
			showKeyword:      { type: 'boolean', default: true },
			showMake:         { type: 'boolean', default: true },
			showModel:        { type: 'boolean', default: true },
			showBodyStyle:    { type: 'boolean', default: true },
			showFuel:         { type: 'boolean', default: true },
			showCondition:    { type: 'boolean', default: true },
			showYear:         { type: 'boolean', default: true },
			showPrice:        { type: 'boolean', default: true },
			showMileage:      { type: 'boolean', default: true },
			showFeatured:     { type: 'boolean', default: true },
			showAccidentFree: { type: 'boolean', default: true },
			className:        { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/search-form', [
			{ type: 'text',   attr: 'heading',     label: __( 'Heading (optional)',     'trx-auto-dealer' ) },
			{ type: 'text',   attr: 'submitLabel', label: __( 'Submit button label',    'trx-auto-dealer' ) },
			{ type: 'text',   attr: 'action',      label: __( 'Submit URL (blank = inventory archive)', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'compact',     label: __( 'Compact (single-row inline form)', 'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Filters shown', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showKeyword',      label: __( 'Keyword',         'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showMake',         label: __( 'Make',            'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showModel',        label: __( 'Model',           'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showBodyStyle',    label: __( 'Body style',      'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showFuel',         label: __( 'Fuel type',       'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showCondition',    label: __( 'Condition',       'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showYear',         label: __( 'Year range',      'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showPrice',        label: __( 'Price range',     'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showMileage',      label: __( 'Mileage range',   'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showFeatured',     label: __( 'Featured only',   'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showAccidentFree', label: __( 'Accident-free only', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- vehicle-grid -----
	registerBlockType( 'trx-auto-dealer/vehicle-grid', {
		title:       __( 'Vehicle Grid', 'trx-auto-dealer' ),
		description: __( 'Grid of vehicle listings with optional filters.', 'trx-auto-dealer' ),
		icon:        'grid-view',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'vehicle', 'trx-auto-dealer' ), __( 'grid', 'trx-auto-dealer' ), __( 'listings', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide', 'full' ] },
		attributes:  {
			perPage:      { type: 'number',  default: 6 },
			columns:      { type: 'number',  default: 3 },
			make:         { type: 'string',  default: '' },
			bodyStyle:    { type: 'string',  default: '' },
			condition:    { type: 'string',  default: '' },
			status:       { type: 'string',  default: '' },
			featured:     { type: 'boolean', default: false },
			orderby:      { type: 'string',  default: 'date' },
			order:        { type: 'string',  default: 'DESC' },
			showMeta:     { type: 'boolean', default: true },
			showLabel:    { type: 'boolean', default: true },
			showFavorite: { type: 'boolean', default: true },
			showCompare:  { type: 'boolean', default: true },
			className:    { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/vehicle-grid', [
			{ type: 'range',       attr: 'perPage',   label: __( 'Posts per page', 'trx-auto-dealer' ), min: 1, max: 24 },
			{ type: 'range',       attr: 'columns',   label: __( 'Columns',        'trx-auto-dealer' ), min: 1, max: 6 },
			{ type: 'termPicker',  attr: 'make',      label: __( 'Make',       'trx-auto-dealer' ), taxonomy: 'makes' },
			{ type: 'termPicker',  attr: 'bodyStyle', label: __( 'Body style', 'trx-auto-dealer' ), taxonomy: 'body_styles' },
			{ type: 'select', attr: 'condition', label: __( 'Condition', 'trx-auto-dealer' ),
				options: [
					{ label: __( 'Any',           'trx-auto-dealer' ), value: '' },
					{ label: __( 'New',           'trx-auto-dealer' ), value: 'new' },
					{ label: __( 'Used',          'trx-auto-dealer' ), value: 'used' },
					{ label: __( 'Certified',     'trx-auto-dealer' ), value: 'certified' },
				]
			},
			{ type: 'select', attr: 'status', label: __( 'Status', 'trx-auto-dealer' ),
				options: [
					{ label: __( 'Any',         'trx-auto-dealer' ), value: '' },
					{ label: __( 'Available',   'trx-auto-dealer' ), value: 'available' },
					{ label: __( 'Reserved',    'trx-auto-dealer' ), value: 'reserved' },
					{ label: __( 'Sold',        'trx-auto-dealer' ), value: 'sold' },
					{ label: __( 'Coming soon', 'trx-auto-dealer' ), value: 'coming_soon' },
				]
			},
			{ type: 'toggle', attr: 'featured', label: __( 'Featured only', 'trx-auto-dealer' ) },
			{ type: 'select', attr: 'orderby', label: __( 'Order by', 'trx-auto-dealer' ),
				options: [
					{ label: __( 'Date',           'trx-auto-dealer' ), value: 'date' },
					{ label: __( 'Price',          'trx-auto-dealer' ), value: 'price' },
					{ label: __( 'Year',           'trx-auto-dealer' ), value: 'year' },
					{ label: __( 'Mileage',        'trx-auto-dealer' ), value: 'mileage' },
					{ label: __( 'Price reduced', 'trx-auto-dealer' ),  value: 'price_reduced' },
					{ label: __( 'Random',         'trx-auto-dealer' ), value: 'rand' },
				]
			},
			{ type: 'select', attr: 'order', label: __( 'Order', 'trx-auto-dealer' ),
				options: [
					{ label: __( 'Descending', 'trx-auto-dealer' ), value: 'DESC' },
					{ label: __( 'Ascending',  'trx-auto-dealer' ), value: 'ASC' },
				]
			},
			{ type: 'heading', label: __( 'Card elements', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showMeta',     label: __( 'Meta (year, mileage, fuel)',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showLabel',    label: __( 'Label (condition + status)',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showFavorite', label: __( 'Like icon (favorite)',        'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showCompare',  label: __( 'Wishlist icon (compare)',     'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- vehicle-card -----
	registerBlockType( 'trx-auto-dealer/vehicle-card', {
		title:       __( 'Vehicle Card', 'trx-auto-dealer' ),
		description: __( 'Single vehicle card with price, key specs and quick actions.', 'trx-auto-dealer' ),
		icon:        'id-alt',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'vehicle', 'trx-auto-dealer' ), __( 'card', 'trx-auto-dealer' ) ],
		supports:    { html: false },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId:    { type: 'number',  default: 0 },
			showMeta:     { type: 'boolean', default: true },
			showLabel:    { type: 'boolean', default: true },
			showFavorite: { type: 'boolean', default: true },
			showCompare:  { type: 'boolean', default: true },
			className:    { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/vehicle-card', [
			{ type: 'vehiclePicker', attr: 'vehicleId',    label: __( 'Vehicle', 'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Card elements', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showMeta',     label: __( 'Meta (year, mileage, fuel)',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showLabel',    label: __( 'Label (condition + status)',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showFavorite', label: __( 'Like icon (favorite)',        'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showCompare',  label: __( 'Wishlist icon (compare)',     'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- specs-table -----
	registerBlockType( 'trx-auto-dealer/specs-table', {
		title:       __( 'Vehicle Specs Table', 'trx-auto-dealer' ),
		description: __( 'Grouped specifications table for a vehicle.', 'trx-auto-dealer' ),
		icon:        'list-view',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'vehicle', 'trx-auto-dealer' ), __( 'specs', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide' ] },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId: { type: 'number', default: 0 },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/specs-table', [
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- contact-form -----
	registerBlockType( 'trx-auto-dealer/contact-form', {
		title:       __( 'Vehicle Contact Form', 'trx-auto-dealer' ),
		description: __( 'Inquiry, test-drive, callback, finance or trade-in form bound to a vehicle.', 'trx-auto-dealer' ),
		icon:        'email-alt',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'inquiry', 'trx-auto-dealer' ), __( 'form', 'trx-auto-dealer' ), __( 'lead', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide' ] },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			formId:    { type: 'string', default: 'inquiry' },
			vehicleId: { type: 'number', default: 0 },
			title:     { type: 'string', default: '' },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/contact-form', [
			{ type: 'select', attr: 'formId', label: __( 'Form type', 'trx-auto-dealer' ),
				options: [
					{ label: __( 'Inquiry',     'trx-auto-dealer' ), value: 'inquiry' },
					{ label: __( 'Test drive',  'trx-auto-dealer' ), value: 'test_drive' },
					{ label: __( 'Callback',    'trx-auto-dealer' ), value: 'callback' },
					{ label: __( 'Finance',     'trx-auto-dealer' ), value: 'finance' },
					{ label: __( 'Trade in',    'trx-auto-dealer' ), value: 'trade_in' },
				]
			},
			{ type: 'text',          attr: 'title',     label: __( 'Heading (optional)', 'trx-auto-dealer' ) },
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (optional — leave blank for unattached form)', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- dealer-info -----
	registerBlockType( 'trx-auto-dealer/dealer-info', {
		title:       __( 'Dealer Info', 'trx-auto-dealer' ),
		description: __( 'Dealer card with logo, address, phone, email and contact actions.', 'trx-auto-dealer' ),
		icon:        'store',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'dealer', 'trx-auto-dealer' ), __( 'contact', 'trx-auto-dealer' ) ],
		supports:    { html: false },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			dealerId:        { type: 'number',  default: 0 },
			vehicleId:       { type: 'number',  default: 0 },
			showLogo:        { type: 'boolean', default: true },
			showHeading:     { type: 'boolean', default: true },
			showPhone:       { type: 'boolean', default: true },
			showEmail:       { type: 'boolean', default: true },
			showAddress:     { type: 'boolean', default: true },
			showWebsite:     { type: 'boolean', default: true },
			showHours:       { type: 'boolean', default: true },
			showMap:         { type: 'boolean', default: true },
			showDescription: { type: 'boolean', default: true },
			showCallBtn:     { type: 'boolean', default: true },
			showWhatsappBtn: { type: 'boolean', default: true },
			showEmailBtn:    { type: 'boolean', default: true },
			className:       { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/dealer-info', [
			{ type: 'dealerPicker',  attr: 'dealerId',  label: __( 'Dealer (overrides vehicle lookup)', 'trx-auto-dealer' ) },
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (resolves the dealer)',     'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Header', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showHeading', label: __( '"Dealer Information" heading', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showLogo',    label: __( 'Logo',                          'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Contact details', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showPhone',       label: __( 'Phone',       'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showEmail',       label: __( 'Email',       'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showAddress',     label: __( 'Address',     'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showWebsite',     label: __( 'Website',     'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showHours',       label: __( 'Hours',       'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showMap',         label: __( 'Map (when coordinates are set)', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showDescription', label: __( 'Description', 'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Action buttons', 'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showCallBtn',     label: __( 'Call Now button',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showWhatsappBtn', label: __( 'WhatsApp button',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showEmailBtn',    label: __( 'Email button',     'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- comparison-table -----
	// Full side-by-side comparison page block. Same surface as the
	// `[trx_ad_compare]` shortcode + Elementor "Comparison Bar" widget.
	var COMPARE_FIELD_OPTIONS = [
		{ value: 'price',            label: __( 'Price', 'trx-auto-dealer' ) },
		{ value: 'sale_price',       label: __( 'Sale Price', 'trx-auto-dealer' ) },
		{ value: 'year',             label: __( 'Year', 'trx-auto-dealer' ) },
		{ value: 'mileage',          label: __( 'Mileage', 'trx-auto-dealer' ) },
		{ value: 'body_style',       label: __( 'Body Style', 'trx-auto-dealer' ) },
		{ value: 'fuel_type',        label: __( 'Fuel Type', 'trx-auto-dealer' ) },
		{ value: 'transmission',     label: __( 'Transmission', 'trx-auto-dealer' ) },
		{ value: 'drivetrain',       label: __( 'Drivetrain', 'trx-auto-dealer' ) },
		{ value: 'condition_type',   label: __( 'Condition', 'trx-auto-dealer' ) },
		{ value: 'doors',            label: __( 'Doors', 'trx-auto-dealer' ) },
		{ value: 'seats',            label: __( 'Seats', 'trx-auto-dealer' ) },
		{ value: 'color_ext',        label: __( 'Exterior Color', 'trx-auto-dealer' ) },
		{ value: 'color_int',        label: __( 'Interior Color', 'trx-auto-dealer' ) },
		{ value: 'engine',           label: __( 'Engine', 'trx-auto-dealer' ) },
		{ value: 'horsepower',       label: __( 'Horsepower', 'trx-auto-dealer' ) },
		{ value: 'torque',           label: __( 'Torque', 'trx-auto-dealer' ) },
		{ value: 'weight',           label: __( 'Weight', 'trx-auto-dealer' ) },
		{ value: 'mpg_combined',     label: __( 'Combined Fuel Economy', 'trx-auto-dealer' ) },
		{ value: 'mpg_city',         label: __( 'City Fuel Economy', 'trx-auto-dealer' ) },
		{ value: 'mpg_highway',      label: __( 'Highway Fuel Economy', 'trx-auto-dealer' ) },
		{ value: 'co2_emissions',    label: __( 'CO₂ Emissions', 'trx-auto-dealer' ) },
		{ value: 'battery_capacity', label: __( 'Battery Capacity (EV)', 'trx-auto-dealer' ) },
		{ value: 'electric_range',   label: __( 'Electric Range (EV)', 'trx-auto-dealer' ) },
		{ value: 'charge_time',      label: __( 'Charge Time (EV)', 'trx-auto-dealer' ) },
		{ value: 'accident_free',    label: __( 'Accident Free', 'trx-auto-dealer' ) },
		{ value: 'vin',              label: __( 'VIN', 'trx-auto-dealer' ) },
		{ value: 'stock_number',     label: __( 'Stock Number', 'trx-auto-dealer' ) },
	];

	registerBlockType( 'trx-auto-dealer/comparison-table', {
		title:       __( 'Comparison Table', 'trx-auto-dealer' ),
		description: __( 'Side-by-side comparison page — image + price + remove × in each column header, spec rows below.', 'trx-auto-dealer' ),
		icon:        'list-view',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'compare', 'trx-auto-dealer' ), __( 'comparison', 'trx-auto-dealer' ), __( 'table', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide', 'full' ] },
		attributes:  {
			heading:      { type: 'string', default: '' },
			emptyMessage: { type: 'string', default: '' },
			fields:       { type: 'array',  default: [ 'price', 'year', 'mileage', 'body_style', 'fuel_type', 'transmission', 'drivetrain', 'condition_type', 'doors', 'color_ext', 'accident_free' ] },
			className:    { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/comparison-table', [
			{ type: 'text',    attr: 'heading',      label: __( 'Heading (optional)', 'trx-auto-dealer' ) },
			{ type: 'text',    attr: 'emptyMessage', label: __( 'Empty-state message (optional)', 'trx-auto-dealer' ) },
			{ type: 'heading', label: __( 'Comparison Fields', 'trx-auto-dealer' ) },
			{ type: 'multiToggle', attr: 'fields', options: COMPARE_FIELD_OPTIONS },
		] ),
		save: dynamicSave,
	} );

	// ----- compare-link -----
	registerBlockType( 'trx-auto-dealer/compare-link', {
		title:       __( 'Compare Link', 'trx-auto-dealer' ),
		description: __( 'Compact link with a live count badge — drop into a header for a quick path to the comparison page.', 'trx-auto-dealer' ),
		icon:        'list-view',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'compare', 'trx-auto-dealer' ), __( 'header', 'trx-auto-dealer' ), __( 'count', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: false },
		attributes:  {
			showLabel:   { type: 'boolean', default: true },
			showIcon:    { type: 'boolean', default: true },
			hideIfEmpty: { type: 'boolean', default: false },
			label:       { type: 'string',  default: '' },
			className:   { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/compare-link', [
			{ type: 'toggle', attr: 'showIcon',    label: __( 'Show icon',  'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'showLabel',   label: __( 'Show label', 'trx-auto-dealer' ) },
			{ type: 'text',   attr: 'label',       label: __( 'Label',      'trx-auto-dealer' ) },
			{ type: 'toggle', attr: 'hideIfEmpty', label: __( 'Hide when empty', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- single-listing -----
	// Renders the entire default single-vehicle layout via SSR. The auto-
	// seeded Gutenberg starter contains exactly this one block, so editor-
	// side registration is mandatory — without it, opening the starter
	// shows "Your site doesn't include support for the X block".
	registerBlockType( 'trx-auto-dealer/single-listing', {
		title:       __( 'Single Listing (Default)', 'trx-auto-dealer' ),
		description: __( 'Renders the full default single-vehicle layout — gallery, specs, description, similar, dealer card + inquiry form.', 'trx-auto-dealer' ),
		icon:        'car',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'single', 'trx-auto-dealer' ), __( 'listing', 'trx-auto-dealer' ), __( 'vehicle', 'trx-auto-dealer' ) ],
		supports:    { html: false },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId: { type: 'number', default: 0 },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/single-listing', [
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (preview)', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- media-slider -----
	registerBlockType( 'trx-auto-dealer/media-slider', {
		title:       __( 'Vehicle Media Slider', 'trx-auto-dealer' ),
		description: __( 'Hero gallery + video slider for the current vehicle.', 'trx-auto-dealer' ),
		icon:        'format-gallery',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'media', 'trx-auto-dealer' ), __( 'gallery', 'trx-auto-dealer' ), __( 'slider', 'trx-auto-dealer' ) ],
		supports:    { html: false },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId: { type: 'number',  default: 0 },
			loop:      { type: 'boolean', default: true },
			className: { type: 'string',  default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/media-slider', [
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (preview)', 'trx-auto-dealer' ) },
			{ type: 'toggle',  attr: 'loop',      label: __( 'Loop slides',       'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- specs-highlights -----
	registerBlockType( 'trx-auto-dealer/specs-highlights', {
		title:       __( 'Vehicle Specs Highlights', 'trx-auto-dealer' ),
		description: __( 'Iconic strip of headline specs — year, mileage, fuel, transmission.', 'trx-auto-dealer' ),
		icon:        'list-view',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'specs', 'trx-auto-dealer' ), __( 'highlights', 'trx-auto-dealer' ) ],
		supports:    { html: false },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId: { type: 'number', default: 0 },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/specs-highlights', [
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (preview)', 'trx-auto-dealer' ) },
		] ),
		save: dynamicSave,
	} );

	// ----- similar-vehicles -----
	registerBlockType( 'trx-auto-dealer/similar-vehicles', {
		title:       __( 'Similar Vehicles', 'trx-auto-dealer' ),
		description: __( 'Up to N listings similar to the current vehicle.', 'trx-auto-dealer' ),
		icon:        'screenoptions',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'similar', 'trx-auto-dealer' ), __( 'related', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide', 'full' ] },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			vehicleId: { type: 'number', default: 0 },
			limit:     { type: 'number', default: 4 },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/similar-vehicles', [
			{ type: 'vehiclePicker', attr: 'vehicleId', label: __( 'Vehicle (preview)', 'trx-auto-dealer' ) },
			{ type: 'number',  attr: 'limit',     label: __( 'Max items',         'trx-auto-dealer' ), min: 1, max: 12 },
		] ),
		save: dynamicSave,
	} );

	// ----- recently-viewed -----
	registerBlockType( 'trx-auto-dealer/recently-viewed', {
		title:       __( 'Recently Viewed Vehicles', 'trx-auto-dealer' ),
		description: __( "Visitor's recently-viewed listings (hydrated from localStorage).", 'trx-auto-dealer' ),
		icon:        'backup',
		category:    'trx-auto-dealer',
		keywords:    [ __( 'recent', 'trx-auto-dealer' ), __( 'history', 'trx-auto-dealer' ) ],
		supports:    { html: false, align: [ 'wide', 'full' ] },
		usesContext: [ 'postId', 'postType' ],
		attributes:  {
			limit:     { type: 'number', default: 4 },
			className: { type: 'string', default: '' },
		},
		edit: makeEdit( 'trx-auto-dealer/recently-viewed', [
			{ type: 'number', attr: 'limit', label: __( 'Max items', 'trx-auto-dealer' ), min: 1, max: 12 },
		] ),
		save: dynamicSave,
	} );

	// Register the "Auto Dealer" category client-side too, so it appears
	// even if the PHP filter hasn't fired yet for this editor instance.
	if ( wp.blocks.getCategories && wp.blocks.setCategories ) {
		var existing = wp.blocks.getCategories();
		var hasOurs  = existing.some( function ( c ) { return c.slug === 'trx-auto-dealer'; } );
		if ( ! hasOurs ) {
			wp.blocks.setCategories( [
				{ slug: 'trx-auto-dealer', title: __( 'Auto Dealer', 'trx-auto-dealer' ), icon: 'car' }
			].concat( existing ) );
		}
	}

} )( window.wp );
