(function (wp) {
	'use strict';

	if (!wp || !wp.blocks || !wp.blockEditor || !wp.components || !wp.element) {
		return;
	}

	var el = wp.element.createElement;
	var Fragment = wp.element.Fragment;
	var registerBlockType = wp.blocks.registerBlockType;
	var InspectorControls = wp.blockEditor.InspectorControls;
	var MediaUpload = wp.blockEditor.MediaUpload;
	var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
	var PanelBody = wp.components.PanelBody;
	var TextControl = wp.components.TextControl;
	var TextareaControl = wp.components.TextareaControl;
	var ToggleControl = wp.components.ToggleControl;
	var Button = wp.components.Button;
	var Notice = wp.components.Notice;
	var ServerSideRender = wp.serverSideRender;
	var __ = wp.i18n.__;

	var blockConfigs = {
		'page-hero': {
			title: 'Source · Page Hero', icon: 'cover-image',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction')]
		},
		gate: {
			title: 'Source · Living Archive Gate', icon: 'columns',
			fields: [field('eyebrow', 'Plaque eyebrow'), field('title', 'Plaque title'), area('lede', 'Plaque text'), field('scrollLabel', 'Scroll cue')],
			repeaters: [repeater('items', 'Hall slices', [field('glyph', 'Greek label'), field('title', 'Hall title'), area('description', 'Description'), field('url', 'Destination URL'), field('buttonLabel', 'Button label'), field('count', 'Count'), field('countLabel', 'Count label'), field('slug', 'Category slug'), media('image', 'Image'), field('imageAlt', 'Image alt text'), field('fallback', 'Bundled fallback filename')])]
		},
		stats: {
			title: 'Source · Statistics Strip', icon: 'chart-bar',
			repeaters: [repeater('items', 'Statistics', [field('value', 'Displayed value'), field('countTo', 'Animated numeric target'), field('label', 'Label')])]
		},
		rooms: {
			title: 'Source · Pantheon Halls', icon: 'building',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction'), field('hint', 'Mobile drag hint')],
			repeaters: [repeater('items', 'Temple cards', [field('glyph', 'Greek label'), field('title', 'Title'), field('latin', 'Latin subtitle'), field('slug', 'Category slug'), field('url', 'Fallback URL'), field('count', 'Fallback count'), field('countLabel', 'Count label'), toggle('inner', 'Inner hall variant'), media('image', 'Image'), field('imageAlt', 'Image alt text'), field('fallback', 'Bundled fallback filename')])]
		},
		top10: {
			title: 'Source · Ranked Archive', icon: 'list-view',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), numberField('postsPerTab', 'Posts per tab')],
			repeaters: [repeater('tabs', 'Query tabs', [field('label', 'Tab label'), field('slug', 'Category slug or all')])]
		},
		featured: {
			title: 'Source · Featured Scroll', icon: 'star-filled',
			fields: [numberField('postId', 'Featured post ID (0 = slug/latest)'), field('postSlug', 'Featured post slug'), field('eyebrow', 'Eyebrow'), field('title', 'Manual title override'), area('lede', 'Manual excerpt override'), media('image', 'Manual image override'), field('tag', 'Image tag'), field('metaOne', 'First metadata label'), field('metaTwo', 'Second metadata label'), field('buttonLabel', 'Button label'), field('buttonUrl', 'Manual URL override')]
		},
		'oracle-band': {
			title: 'Source · Oracle Band', icon: 'lightbulb',
			fields: [area('quote', 'Quote'), field('buttonLabel', 'Button label'), field('buttonUrl', 'Button URL')]
		},
		'newsletter-section': {
			title: 'Source · Newsletter Section', icon: 'email-alt',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction'), field('placeholder', 'Email placeholder'), field('buttonLabel', 'Button label'), field('source', 'Subscription source key')]
		},
		manifesto: {
			title: 'Source · Manifesto', icon: 'editor-quote',
			fields: [area('lead', 'Lead statement (basic emphasis allowed)')],
			repeaters: [repeater('paragraphs', 'Manifesto paragraphs', [area('text', 'Paragraph')])]
		},
		pillars: {
			title: 'Source · Principles', icon: 'screenoptions',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title')],
			repeaters: [repeater('items', 'Principles', [field('title', 'Title'), area('body', 'Description'), field('icon', 'Icon key')])]
		},
		timeline: {
			title: 'Source · Timeline', icon: 'backup',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title')],
			repeaters: [repeater('items', 'Timeline entries', [field('year', 'Year'), field('title', 'Title'), area('body', 'Description')])]
		},
		process: {
			title: 'Source · Editorial Process', icon: 'yes-alt',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction')],
			repeaters: [repeater('items', 'Process gates', [field('number', 'Number'), field('title', 'Title'), area('body', 'Description'), field('note', 'Outcome note'), toggle('success', 'Successful outcome')])]
		},
		keeper: {
			title: 'Source · Archive Keeper', icon: 'admin-users',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('body', 'Biography'), media('image', 'Portrait'), field('buttonLabel', 'Button label'), field('buttonUrl', 'Button URL')]
		},
		'oracle-hero': {
			title: 'Source · Oracle Hero', icon: 'visibility',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction'), area('quote', 'Oracle quote')]
		},
		'oracle-cards': {
			title: 'Source · Oracle Question Families', icon: 'grid-view',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title')],
			repeaters: [repeater('items', 'Question families', [field('number', 'Number'), field('title', 'Title'), area('body', 'Description'), field('icon', 'Icon key')])]
		},
		'oracle-ask': {
			title: 'Source · Ask the Oracle', icon: 'format-chat',
			fields: [field('eyebrow', 'Eyebrow'), field('title', 'Title'), area('lede', 'Introduction'), field('buttonLabel', 'Button label'), field('buttonUrl', 'Button URL')]
		},
		'faq-list': {
			title: 'Source · FAQ List', icon: 'editor-help',
			fields: [field('ctaTitle', 'Closing title'), area('ctaBody', 'Closing text'), field('buttonLabel', 'Button label'), field('buttonUrl', 'Button URL')],
			repeaters: [repeater('tabs', 'FAQ filter tabs', [field('label', 'Label'), field('slug', 'Category key')]), repeater('items', 'Questions', [field('question', 'Question'), area('answer', 'Answer'), field('category', 'Category key')])]
		},
		'contact-layout': {
			title: 'Source · Contact Layout', icon: 'email',
			fields: [field('eyebrow', 'Form eyebrow'), field('title', 'Form title'), area('lede', 'Form introduction'), field('email', 'Contact email override'), area('quote', 'Sidebar quote (basic emphasis allowed)')],
			repeaters: [repeater('channels', 'Contact channels', [field('title', 'Title'), area('body', 'Description'), field('icon', 'Icon key'), field('kind', 'Kind (email or link)'), field('value', 'Displayed value'), field('url', 'Destination URL')]), repeater('stats', 'Response statistics', [field('value', 'Value'), field('label', 'Label')])]
		},
		recipe: {
			title: 'Source · Recipe Body', icon: 'food',
			fields: [field('ingredientsTitle', 'Ingredients title'), field('ratioLabel', 'Ratio label'), field('ratioValue', 'Ratio value'), field('ratioBody', 'Ratio explanation'), field('equipmentTitle', 'Equipment title'), field('tipsTitle', 'Tips title'), field('mediaEyebrow', 'Media eyebrow'), field('mediaTitle', 'Media title'), area('mediaLede', 'Media introduction'), field('videoPosterUrl', 'Video poster URL'), field('videoId', 'YouTube video ID'), field('videoLabel', 'Video label'), field('videoDuration', 'Video duration')],
			repeaters: [repeater('ingredients', 'Ingredients', [field('name', 'Ingredient'), field('amount', 'Amount')]), repeater('equipment', 'Equipment', [field('text', 'Item')]), repeater('steps', 'Method steps', [field('title', 'Step title'), area('body', 'Instructions'), field('time', 'Time')]), repeater('tips', 'Test notes', [field('text', 'Note')]), repeater('gallery', 'Gallery', [media('image', 'Image'), field('caption', 'Caption'), field('fallback', 'Bundled fallback filename')])]
		}
	};

	function field(key, label) { return { key: key, label: label, type: 'text' }; }
	function area(key, label) { return { key: key, label: label, type: 'textarea' }; }
	function toggle(key, label) { return { key: key, label: label, type: 'toggle' }; }
	function numberField(key, label) { return { key: key, label: label, type: 'number' }; }
	function media(key, label) { return { key: key, label: label, type: 'media' }; }
	function repeater(key, label, fields) { return { key: key, label: label, fields: fields }; }

	function updateItem(items, index, key, value) {
		var next = (items || []).map(function (item, itemIndex) {
			if (itemIndex !== index) { return item; }
			var copy = Object.assign({}, item || {});
			copy[key] = value;
			return copy;
		});
		return next;
	}

	function moveItem(items, index, direction) {
		var next = (items || []).slice();
		var target = index + direction;
		if (target < 0 || target >= next.length) { return next; }
		var current = next[index];
		next[index] = next[target];
		next[target] = current;
		return next;
	}

	function FieldControl(props) {
		var spec = props.spec;
		var value = props.value;
		var onChange = props.onChange;

		if (spec.type === 'textarea') {
			return el(TextareaControl, { label: __(spec.label, 'hapantheon'), value: value || '', rows: 4, onChange: onChange });
		}
		if (spec.type === 'toggle') {
			return el(ToggleControl, { label: __(spec.label, 'hapantheon'), checked: !!value, onChange: onChange });
		}
		if (spec.type === 'number') {
			return el(TextControl, { label: __(spec.label, 'hapantheon'), type: 'number', value: value || 0, onChange: function (next) { onChange(parseInt(next || '0', 10)); } });
		}
		if (spec.type === 'media') {
			var imageIdKey = spec.key + 'Id';
			var imageUrlKey = spec.key + 'Url';
			return el('div', { className: 'hapantheon-source-media-control' },
				el('strong', null, __(spec.label, 'hapantheon')),
				props.item && props.item[imageUrlKey] ? el('img', { src: props.item[imageUrlKey], alt: '' }) : null,
				el(MediaUploadCheck, null,
					el(MediaUpload, {
						onSelect: function (mediaObject) {
							props.onMediaChange(imageIdKey, mediaObject.id || 0);
							props.onMediaChange(imageUrlKey, mediaObject.url || '');
						},
						allowedTypes: ['image'],
						value: props.item ? props.item[imageIdKey] : 0,
						render: function (mediaProps) { return el(Button, { variant: 'secondary', onClick: mediaProps.open }, __('Choose image', 'hapantheon')); }
					})
				),
				el(TextControl, { label: __('Image URL', 'hapantheon'), value: props.item && props.item[imageUrlKey] ? props.item[imageUrlKey] : '', onChange: function (next) { props.onMediaChange(imageUrlKey, next); } })
			);
		}
		return el(TextControl, { label: __(spec.label, 'hapantheon'), value: value || '', onChange: onChange });
	}

	function ScalarControls(props) {
		return (props.fields || []).map(function (spec) {
			if (spec.type === 'media') {
				return el(FieldControl, {
					key: spec.key,
					spec: spec,
					item: props.attributes,
					onMediaChange: function (key, value) { var patch = {}; patch[key] = value; props.setAttributes(patch); }
				});
			}
			return el(FieldControl, {
				key: spec.key,
				spec: spec,
				value: props.attributes[spec.key],
				onChange: function (value) { var patch = {}; patch[spec.key] = value; props.setAttributes(patch); }
			});
		});
	}

	function RepeaterControls(props) {
		var items = Array.isArray(props.attributes[props.repeater.key]) ? props.attributes[props.repeater.key] : [];
		function commit(next) { var patch = {}; patch[props.repeater.key] = next; props.setAttributes(patch); }

		return el(PanelBody, { title: __(props.repeater.label, 'hapantheon'), initialOpen: false },
			items.map(function (item, index) {
				return el('div', { className: 'hapantheon-source-repeater-item', key: index },
					el('div', { className: 'hapantheon-source-repeater-heading' },
						el('strong', null, '#' + (index + 1)),
						el('span', null,
							el(Button, { size: 'small', icon: 'arrow-up-alt2', label: __('Move up', 'hapantheon'), disabled: index === 0, onClick: function () { commit(moveItem(items, index, -1)); } }),
							el(Button, { size: 'small', icon: 'arrow-down-alt2', label: __('Move down', 'hapantheon'), disabled: index === items.length - 1, onClick: function () { commit(moveItem(items, index, 1)); } }),
							el(Button, { size: 'small', isDestructive: true, icon: 'trash', label: __('Remove', 'hapantheon'), onClick: function () { commit(items.filter(function (_, itemIndex) { return itemIndex !== index; })); } })
						)
					),
					props.repeater.fields.map(function (spec) {
						if (spec.type === 'media') {
							return el(FieldControl, {
								key: spec.key,
								spec: spec,
								item: item || {},
								onMediaChange: function (key, value) { commit(updateItem(items, index, key, value)); }
							});
						}
						return el(FieldControl, {
							key: spec.key,
							spec: spec,
							value: item ? item[spec.key] : '',
							onChange: function (value) { commit(updateItem(items, index, spec.key, value)); }
						});
					})
				);
			}),
			el(Button, { variant: 'secondary', onClick: function () { commit(items.concat([{}])); } }, __('Add item', 'hapantheon'))
		);
	}

	Object.keys(blockConfigs).forEach(function (slug) {
		var config = blockConfigs[slug];
		registerBlockType('hapantheon/' + slug, {
			apiVersion: 2,
			title: __(config.title, 'hapantheon'),
			attributes: window.hapantheonSourceBlocks && window.hapantheonSourceBlocks.definitions && window.hapantheonSourceBlocks.definitions[slug] ? window.hapantheonSourceBlocks.definitions[slug].attributes : {},
			category: 'design',
			icon: config.icon,
			supports: { html: false, anchor: true, align: ['full'] },
			edit: function (props) {
				return el(Fragment, null,
					el(InspectorControls, null,
						el(PanelBody, { title: __('Source fields', 'hapantheon'), initialOpen: true },
							el(Notice, { status: 'info', isDismissible: false }, __('Frontend markup is generated by the bundled source renderer. Layout wrappers are intentionally unavailable.', 'hapantheon')),
							el(ScalarControls, { fields: config.fields || [], attributes: props.attributes, setAttributes: props.setAttributes })
						),
						(config.repeaters || []).map(function (spec) { return el(RepeaterControls, { key: spec.key, repeater: spec, attributes: props.attributes, setAttributes: props.setAttributes }); })
					),
					el('div', { className: 'hapantheon-source-block-editor-preview' },
						ServerSideRender ? el(ServerSideRender, { block: 'hapantheon/' + slug, attributes: props.attributes, httpMethod: 'POST' }) : el('p', null, __('Source preview is unavailable in this WordPress build.', 'hapantheon'))
					)
				);
			},
			save: function () { return null; }
		});
	});
}(window.wp));
