/**
 * Basic Forms - Form Builder
 *
 * @package BasicForms
 * @since 1.0.0
 */
(function($){
		$(function(){
		var fieldCounter = 0;
		var formFields = [];
		var editorConfig = typeof wppsBfEditorData !== 'undefined' ? wppsBfEditorData : {};
		var isPro = !!editorConfig.isPro;
		var licenseUrl = editorConfig.licenseUrl || '';

		// Defined before the initial render loop below, which calls renderField →
		// conditionalRuleRow and reads these labels while building each field.
		var conditionalOperatorLabels = {
			equals: 'is equal to',
			not_equals: 'is not equal to',
			contains: 'contains',
			not_empty: 'is not empty',
			empty: 'is empty'
		};

		var existing = $('#wpps-bf-form-fields-data').val();
		if (existing) {
			try {
				formFields = JSON.parse(existing);
				formFields.forEach(function(f){
					// Saved meta returns ids as strings ("5"); jQuery's .data('id') yields
					// numbers, so normalize here or syncFieldFromDom can't match the field.
					f.id = parseInt(f.id, 10);
					if (isNaN(f.id)) { f.id = fieldCounter; }
					if (f.type !== 'separator' && f.type !== 'group' && f.type !== 'html' && !f.field_id) {
						f.field_id = ensureUniqueFieldId(slugFromLabel(f.label), f.id);
					}
					renderField(f);
					if (f.id >= fieldCounter) fieldCounter = f.id + 1;
				});
			} catch(e) {
				if (window.console && console.error) {
					console.error('Basic Forms: failed to render saved fields', e);
				}
			}
		}

		function slugFromLabel(label) {
			if (!label || typeof label !== 'string') return '';
			return label.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '') || '';
		}
		function ensureUniqueFieldId(base, fid) {
			var slug = (base || 'field').replace(/_+\d+$/, '');
			return slug + '_' + fid;
		}
		function escAttr(val) {
			return (val || '').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
		}
		function isLayoutField(type) {
			return type === 'separator' || type === 'group' || type === 'html';
		}
		function optionLines(options) {
			return (options || '').split('\n').map(function(o){ return o.trim(); }).filter(Boolean);
		}
		function hasMultipleCheckboxOptions(f) {
			return f.type === 'checkbox' && optionLines(f.options).length > 1;
		}

		$(document).on('click', '.wpps-bf-add-field', function(){
			var $btn = $(this);
			var type = $btn.data('type');
			var label = '';
			if (type === 'separator') {
				label = '';
			} else if (type === 'group') {
				label = 'Section Title';
			} else if (type === 'html') {
				label = 'HTML Block';
			} else {
				label = type.charAt(0).toUpperCase() + type.slice(1) + ' Field';
			}
			var fid = fieldCounter++;
			var field = {
				id: fid,
				type: type,
				field_id: '',
				label: label,
				placeholder: '',
				required: false,
				help: '',
				options: '',
				description: '',
				content: type === 'html' ? '<p>Your content here.</p>' : '',
				rows: '5',
				maxlength: '',
				step: '',
				default_value: '',
				checkbox_label: '',
				empty_label: '',
				default_country: '1',
				minlength: '8'
			};
			if (!isLayoutField(type)) {
				field.field_id = ensureUniqueFieldId(slugFromLabel(label), fid);
			}
			formFields.push(field);
			renderField(field);
			if ($('#wpps-bf-fields-container').sortable('instance')) {
				$('#wpps-bf-fields-container').sortable('refresh');
			}
			updateData();
		});

		function appendWidthRow(f, pid, html) {
			html += '<div class="wpps-bf-field-row wpps-bf-field-id-width"><p><label for="' + pid + '-field-id">Field ID</label><input type="text" id="' + pid + '-field-id" class="field-field-id" value="' + escAttr(f.field_id || 'field_' + f.id) + '" readonly></p>';
			html += '<p><label for="' + pid + '-width">Width</label><select id="' + pid + '-width" class="field-width"><option value="">Full (100%)</option><option value="half"' + (f.width === 'half' ? ' selected' : '') + '>Half (50%)</option><option value="third"' + (f.width === 'third' ? ' selected' : '') + '>Third (33%)</option><option value="quarter"' + (f.width === 'quarter' ? ' selected' : '') + '>Quarter (25%)</option><option value="40"' + (f.width === '40' ? ' selected' : '') + '>40%</option><option value="60"' + (f.width === '60' ? ' selected' : '') + '>60%</option></select></p></div>';
			return html;
		}

		function appendTypeSettings(f, pid, html) {
			if (['select','radio','checkbox'].indexOf(f.type) >= 0) {
				html += '<p><label for="' + pid + '-options">Options (one per line)</label><textarea id="' + pid + '-options" class="field-options" rows="3">' + escAttr(f.options || '') + '</textarea></p>';
			}
			if (f.type === 'select') {
				html += '<p><label for="' + pid + '-empty-label">Empty option label</label><input type="text" id="' + pid + '-empty-label" class="field-empty-label" value="' + escAttr(f.empty_label || '') + '" placeholder="Select"></p>';
			}
			if (f.type === 'checkbox' && !hasMultipleCheckboxOptions(f)) {
				html += '<p><label for="' + pid + '-checkbox-label">Checkbox label</label><input type="text" id="' + pid + '-checkbox-label" class="field-checkbox-label" value="' + escAttr(f.checkbox_label || '') + '" placeholder="I agree to the terms"></p>';
			}
			if (f.type === 'number' || f.type === 'date' || f.type === 'time' || f.type === 'datetime') {
				html += '<p><label for="' + pid + '-min">Min</label><input type="' + (f.type === 'number' ? 'number' : 'text') + '" id="' + pid + '-min" class="field-min" value="' + escAttr(f.min || '') + '"> <label for="' + pid + '-max">Max</label><input type="' + (f.type === 'number' ? 'number' : 'text') + '" id="' + pid + '-max" class="field-max" value="' + escAttr(f.max || '') + '"></p>';
			}
			if (f.type === 'number') {
				html += '<p><label for="' + pid + '-step">Step</label><input type="text" id="' + pid + '-step" class="field-step" value="' + escAttr(f.step || '') + '" placeholder="1"> <label for="' + pid + '-default">Default value</label><input type="number" id="' + pid + '-default" class="field-default" value="' + escAttr(f.default_value || '') + '"></p>';
			}
			if (f.type === 'textarea') {
				html += '<p><label for="' + pid + '-rows">Rows</label><input type="number" id="' + pid + '-rows" class="field-rows" value="' + escAttr(f.rows || '5') + '" min="2" max="20"> <label for="' + pid + '-maxlength">Max length</label><input type="number" id="' + pid + '-maxlength" class="field-maxlength" value="' + escAttr(f.maxlength || '') + '" min="1"></p>';
			}
			if (['text','email','url'].indexOf(f.type) >= 0) {
				html += '<p><label for="' + pid + '-maxlength">Max length</label><input type="number" id="' + pid + '-maxlength" class="field-maxlength" value="' + escAttr(f.maxlength || '') + '" min="1"> <label for="' + pid + '-default">Default value</label><input type="text" id="' + pid + '-default" class="field-default" value="' + escAttr(f.default_value || '') + '"></p>';
			}
			if (f.type === 'file') {
				html += '<p><label for="' + pid + '-file-types">Allowed types</label><input type="text" id="' + pid + '-file-types" class="field-file-types" value="' + escAttr(f.file_types || 'image/*,.pdf') + '"><span class="wpps-bf-help">e.g. image/*,.pdf,.doc,.docx</span></p>';
				html += '<p><label for="' + pid + '-max-size">Max size (MB)</label><input type="number" id="' + pid + '-max-size" class="field-max-size" value="' + escAttr(f.max_size || '5') + '" min="1" max="50"></p>';
				html += '<p><label><input type="checkbox" class="field-multiple" ' + (f.multiple ? 'checked' : '') + '> Allow multiple</label></p>';
			}
			if (f.type === 'phone') {
				html += '<p><label for="' + pid + '-default-country">Default country code</label><input type="text" id="' + pid + '-default-country" class="field-default-country" value="' + escAttr(f.default_country || '1') + '" placeholder="1"></p>';
			}
			if (f.type === 'password') {
				html += '<p><label for="' + pid + '-minlength">Minimum length</label><input type="number" id="' + pid + '-minlength" class="field-minlength" value="' + escAttr(f.minlength || '8') + '" min="1" max="128"></p>';
			}
			if (f.type === 'hidden') {
				html += '<p><label for="' + pid + '-default">Default value</label><input type="text" id="' + pid + '-default" class="field-default" value="' + escAttr(f.default_value || '') + '"></p>';
			}
			return html;
		}

		function conditionalValueControl(controllerFieldId, currentValue, controlId) {
			var value = currentValue || '';
			var idAttr = controlId ? ' id="' + escAttr(controlId) + '"' : '';
			var controller = controllerFieldId
				? formFields.filter(function (x) { return x.field_id === controllerFieldId; })[0]
				: null;
			var opts = (controller && (controller.type === 'select' || controller.type === 'radio' || controller.type === 'checkbox'))
				? optionLines(controller.options)
				: [];

			// A single checkbox (no options) submits "1" when ticked.
			var choices = opts.map(function (o) { return { value: o, label: o }; });
			if (!choices.length && controller && controller.type === 'checkbox') {
				choices = [{ value: '1', label: 'Checked' }];
			}

			if (!choices.length) {
				return '<input type="text"' + idAttr + ' class="field-show-if-value" value="' + escAttr(value) + '" placeholder="e.g. Other">';
			}

			var out = '<select' + idAttr + ' class="field-show-if-value"><option value="">— Select a value —</option>';
			var matched = false;
			choices.forEach(function (c) {
				var selected = (c.value === value) ? ' selected' : '';
				if (selected) { matched = true; }
				out += '<option value="' + escAttr(c.value) + '"' + selected + '>' + escAttr(c.label) + '</option>';
			});
			if (value && !matched) {
				out += '<option value="' + escAttr(value) + '" selected>' + escAttr(value) + '</option>';
			}
			out += '</select>';
			return out;
		}

		// Accept both the legacy single-rule shape and the multi-rule shape.
		function normalizeBuilderShowIf(showIf) {
			if (!showIf || typeof showIf !== 'object') {
				return { relation: 'and', rules: [] };
			}
			var relation = (String(showIf.relation || 'and').toLowerCase() === 'or') ? 'or' : 'and';
			var rules = [];
			if (Array.isArray(showIf.rules)) {
				rules = showIf.rules.filter(function (r) { return r && r.field_id; }).map(function (r) {
					return { field_id: r.field_id, operator: r.operator || 'equals', value: r.value || '' };
				});
			} else if (showIf.field_id) {
				rules = [{ field_id: showIf.field_id, operator: showIf.operator || 'equals', value: showIf.value || '' }];
			}
			return { relation: relation, rules: rules };
		}

		function conditionalRuleRow(otherFields, rule) {
			rule = rule || {};
			var operator = rule.operator || 'equals';
			var valueless = operator === 'empty' || operator === 'not_empty';

			var h = '<div class="wpps-bf-conditional-rule">';
			h += '<div class="wpps-bf-conditional-grid' + (valueless ? ' is-value-hidden' : '') + '">';

			h += '<p><label>Field</label><select class="field-show-if-field"><option value="">— Select a field —</option>';
			otherFields.forEach(function (of) {
				h += '<option value="' + escAttr(of.field_id) + '"' + (rule.field_id === of.field_id ? ' selected' : '') + '>' + escAttr(of.label || of.field_id) + '</option>';
			});
			h += '</select></p>';

			h += '<p><label>Condition</label><select class="field-show-if-operator">';
			['equals', 'not_equals', 'contains', 'not_empty', 'empty'].forEach(function (op) {
				h += '<option value="' + op + '"' + (operator === op ? ' selected' : '') + '>' + conditionalOperatorLabels[op] + '</option>';
			});
			h += '</select></p>';

			h += '<p class="wpps-bf-conditional-value' + (valueless ? ' is-hidden' : '') + '"><label>Value</label>' + conditionalValueControl(rule.field_id, rule.value, '') + '</p>';

			h += '</div>';
			h += '<button type="button" class="wpps-bf-remove-condition" title="Remove condition" aria-label="Remove condition"><span class="dashicons dashicons-no-alt" aria-hidden="true"></span></button>';
			h += '</div>';
			return h;
		}

		function appendConditionalRow(f, pid, html) {
			if (!isPro) {
				html += '<div class="wpps-bf-premium-locked-note">';
				html += '<span class="wpps-pro-badge">Premium</span> ';
				html += 'Conditional visibility requires a license.';
				if (licenseUrl) {
					html += ' <a href="' + escAttr(licenseUrl) + '">Activate your license</a>';
				}
				html += '</div>';
				return html;
			}
			var otherFields = formFields.filter(function (x) {
				return x.id !== f.id && !isLayoutField(x.type) && x.field_id;
			});
			if (!otherFields.length) {
				return html;
			}
			var config = normalizeBuilderShowIf(f.show_if);
			var enabled = config.rules.length > 0;
			var rulesToRender = config.rules.length ? config.rules : [{}];

			html += '<div class="wpps-bf-conditional-settings' + (enabled ? ' is-enabled' : '') + '">';
			html += '<label class="wpps-bf-conditional-toggle"><input type="checkbox" class="field-conditional-enable"' + (enabled ? ' checked' : '') + '><span class="dashicons dashicons-visibility" aria-hidden="true"></span>Conditional visibility</label>';
			html += '<div class="wpps-bf-conditional-body"' + (enabled ? '' : ' hidden') + '>';

			html += '<p class="wpps-bf-conditional-relation"><span>Show this field when</span> <select class="field-show-if-relation"><option value="and"' + (config.relation === 'and' ? ' selected' : '') + '>all</option><option value="or"' + (config.relation === 'or' ? ' selected' : '') + '>any</option></select> <span>of these conditions match:</span></p>';

			html += '<div class="wpps-bf-conditional-rules">';
			rulesToRender.forEach(function (rule) {
				html += conditionalRuleRow(otherFields, rule);
			});
			html += '</div>';

			html += '<button type="button" class="button wpps-bf-add-condition"><span class="dashicons dashicons-plus-alt2" aria-hidden="true"></span> Add condition</button>';
			html += '<span class="wpps-bf-help">This field stays hidden until the conditions above are met.</span>';
			html += '</div></div>';
			return html;
		}

		function renderField(f){
			var isLayout = isLayoutField(f.type);
			var cls = 'wpps-bf-form-field-item collapsed' + (isLayout ? ' wpps-bf-field-layout' : '');
			var typeLabel = f.type.charAt(0).toUpperCase() + f.type.slice(1);
			var html = '<div class="' + cls + '" data-id="' + f.id + '"><div class="wpps-bf-field-header"><span class="wpps-bf-field-drag dashicons dashicons-menu" title="Drag to reorder"></span>';

			if (f.type === 'separator') {
				html += '<span class="wpps-bf-field-title">— Separator —</span><span class="wpps-bf-field-type">' + typeLabel + '</span>';
			} else if (f.type === 'group') {
				html += '<span class="wpps-bf-field-title">' + escAttr(f.label || 'Section') + '</span><span class="wpps-bf-field-type">' + typeLabel + '</span>';
			} else if (f.type === 'html') {
				html += '<span class="wpps-bf-field-title">' + escAttr(f.label || 'HTML Block') + '</span><span class="wpps-bf-field-type">' + typeLabel + '</span>';
			} else {
				var displayLabel = f.label || (f.type.charAt(0).toUpperCase() + f.type.slice(1) + ' Field');
				html += '<span class="wpps-bf-field-title">' + escAttr(displayLabel) + '</span><span class="wpps-bf-field-type">' + typeLabel + '</span><span class="wpps-bf-field-id-badge" title="Field ID">' + escAttr(f.field_id || 'field_' + f.id) + '</span>' + (f.required ? ' <span class="wpps-bf-required">*</span>' : '');
			}
			html += '<div class="wpps-bf-field-actions"><button type="button" class="wpps-bf-field-btn duplicate-field" title="Duplicate"><span class="dashicons dashicons-admin-page"></span></button><button type="button" class="wpps-bf-field-btn delete-field" title="Delete"><span class="dashicons dashicons-trash"></span></button></div></div><div class="wpps-bf-field-body">';

			if (f.type === 'separator') {
				html += '<p style="color:var(--wpps-bf-gray, #646970);margin:0;">Adds a horizontal line.</p>';
			} else if (f.type === 'group') {
				var pid = 'wpps-bf-f' + f.id;
				html += '<p><label for="' + pid + '-label">Section Title</label><input type="text" id="' + pid + '-label" class="field-label" value="' + escAttr(f.label || '') + '"></p>';
				html += '<p><label for="' + pid + '-desc">Description</label><input type="text" id="' + pid + '-desc" class="field-description" value="' + escAttr(f.description || '') + '"></p>';
			} else if (f.type === 'html') {
				var pid = 'wpps-bf-f' + f.id;
				html = appendWidthRow(f, pid, html);
				html += '<p><label for="' + pid + '-label">Admin label (builder only)</label><input type="text" id="' + pid + '-label" class="field-label" value="' + escAttr(f.label || '') + '"></p>';
				html += '<p><label for="' + pid + '-content">HTML content</label><textarea id="' + pid + '-content" class="field-content" rows="6">' + escAttr(f.content || '') + '</textarea><span class="wpps-bf-help">Allowed HTML tags are sanitized on save. Not submitted with the form.</span></p>';
			} else {
				var pid = 'wpps-bf-f' + f.id;
				html += '<p><label for="' + pid + '-label">Label</label><input type="text" id="' + pid + '-label" class="field-label" value="' + escAttr(f.label || '') + '"></p>';
				if (f.type !== 'hidden' && f.type !== 'password') {
					html += '<p><label for="' + pid + '-placeholder">Placeholder</label><input type="text" id="' + pid + '-placeholder" class="field-placeholder" value="' + escAttr(f.placeholder || '') + '"></p>';
				} else if (f.type === 'password') {
					html += '<p><label for="' + pid + '-placeholder">Placeholder</label><input type="text" id="' + pid + '-placeholder" class="field-placeholder" value="' + escAttr(f.placeholder || '') + '"></p>';
				}
				html = appendWidthRow(f, pid, html);
				html = appendTypeSettings(f, pid, html);
				if (f.type !== 'hidden') {
					html += '<p><label for="' + pid + '-help">Help text</label><input type="text" id="' + pid + '-help" class="field-help" value="' + escAttr(f.help || '') + '"></p>';
					html += '<div class="wpps-bf-field-row wpps-bf-required-inline-row"><p style="margin:0;display:flex;flex-wrap:wrap;align-items:center;gap:16px;"><label style="margin:0;"><input type="checkbox" class="field-required" ' + (f.required ? 'checked' : '') + '> Required</label>';
					if (f.type === 'checkbox' || f.type === 'radio') {
						html += '<label style="margin:0;"><input type="checkbox" class="field-inline" ' + (f.inline ? 'checked' : '') + '> Inline</label>';
						html += '<span class="wpps-bf-cols-wrap" style="' + (f.inline ? '' : 'display:none;') + '"><label for="' + pid + '-cols">Columns</label> <select id="' + pid + '-cols" class="field-cols"><option value="2"' + (f.cols === '2' ? ' selected' : '') + '>2</option><option value="3"' + (f.cols === '3' || !f.cols ? ' selected' : '') + '>3</option><option value="4"' + (f.cols === '4' ? ' selected' : '') + '>4</option><option value="5"' + (f.cols === '5' ? ' selected' : '') + '>5</option></select></span>';
					}
					html += '</p></div>';
				} else {
					html += '<p><label><input type="checkbox" class="field-required" ' + (f.required ? 'checked' : '') + '> Required</label></p>';
				}
				html = appendConditionalRow(f, pid, html);
			}
			html += '</div></div>';
			$('#wpps-bf-fields-container').append(html);
		}

		function syncFieldFromDom($item, id) {
			var f = formFields.find(function(x){ return x.id === id; });
			if (!f) return;

			if (f.type === 'separator') {
				return;
			}

			if (f.type === 'html') {
				f.label = $item.find('.field-label').val() || 'HTML Block';
				f.width = $item.find('.field-width').val() || '';
				f.content = $item.find('.field-content').val() || '';
				var fidInput = $item.find('.field-field-id').val();
				if (fidInput) {
					f.field_id = fidInput.replace(/[^a-z0-9_]/gi, '_').replace(/_+/g, '_').replace(/^_|_$/g, '') || ensureUniqueFieldId(slugFromLabel(f.label), f.id);
				}
				return;
			}

			var $label = $item.find('.field-label');
			if (!$label.length) return;
			var newLabel = $label.val();
			var fidInput = $item.find('.field-field-id').val();
			if (fidInput) {
				f.field_id = fidInput.replace(/[^a-z0-9_]/gi, '_').replace(/_+/g, '_').replace(/^_|_$/g, '') || ensureUniqueFieldId(slugFromLabel(newLabel), f.id);
			} else if (newLabel) {
				f.field_id = ensureUniqueFieldId(slugFromLabel(newLabel), f.id);
			} else {
				f.field_id = 'field_' + f.id;
			}
			f.label = newLabel || '';
			f.width = $item.find('.field-width').val() || '';
			f.placeholder = $item.find('.field-placeholder').val() || '';
			f.help = $item.find('.field-help').val() || '';
			f.required = $item.find('.field-required').is(':checked');
			if (f.type === 'checkbox' || f.type === 'radio') {
				f.inline = $item.find('.field-inline').is(':checked');
				f.cols = $item.find('.field-cols').val() || '3';
			}
			f.options = $item.find('.field-options').val() || '';
			f.min = $item.find('.field-min').val() || '';
			f.max = $item.find('.field-max').val() || '';
			f.step = $item.find('.field-step').val() || '';
			f.rows = $item.find('.field-rows').val() || '';
			f.maxlength = $item.find('.field-maxlength').val() || '';
			f.minlength = $item.find('.field-minlength').val() || '';
			f.file_types = $item.find('.field-file-types').val() || '';
			f.max_size = $item.find('.field-max-size').val() || '';
			f.multiple = $item.find('.field-multiple').is(':checked');
			f.description = $item.find('.field-description').val() || '';
			f.default_value = $item.find('.field-default').val() || '';
			f.checkbox_label = $item.find('.field-checkbox-label').val() || '';
			f.empty_label = $item.find('.field-empty-label').val() || '';
			f.default_country = $item.find('.field-default-country').val() || '';
			if ($item.find('.field-conditional-enable').is(':checked')) {
				var relation = ($item.find('.field-show-if-relation').val() === 'or') ? 'or' : 'and';
				var rules = [];
				$item.find('.wpps-bf-conditional-rule').each(function () {
					var $rule = $(this);
					var ruleField = $rule.find('.field-show-if-field').val() || '';
					if (!ruleField) {
						return;
					}
					var op = $rule.find('.field-show-if-operator').val() || 'equals';
					var val = (op === 'empty' || op === 'not_empty') ? '' : ($rule.find('.field-show-if-value').val() || '');
					rules.push({ field_id: ruleField, operator: op, value: val });
				});
				if (rules.length) {
					f.show_if = { relation: relation, rules: rules };
				} else {
					delete f.show_if;
				}
			} else {
				delete f.show_if;
			}
		}

		function updateFieldHeader($item, f) {
			var displayLabel;
			if (f.type === 'group') {
				displayLabel = f.label || 'Section';
			} else if (f.type === 'html') {
				displayLabel = f.label || 'HTML Block';
			} else if (f.type === 'separator') {
				return;
			} else {
				displayLabel = f.label || (f.type.charAt(0).toUpperCase() + f.type.slice(1) + ' Field');
			}
			$item.find('.wpps-bf-field-title').first().text(displayLabel);
			if (!isLayoutField(f.type)) {
				$item.find('.wpps-bf-field-id-badge').text(f.field_id || 'field_' + f.id);
			}
		}

		$(document).on('click', '.wpps-bf-field-header', function(e){
			if ($(e.target).closest('.wpps-bf-field-actions, .wpps-bf-field-drag').length) return;
			$(this).closest('.wpps-bf-form-field-item').toggleClass('collapsed');
		});

		$(document).on('change', '.field-inline', function(){
			var $item = $(this).closest('.wpps-bf-form-field-item');
			$item.find('.wpps-bf-cols-wrap').toggle($(this).is(':checked'));
		});

		$(document).on('change', '.field-show-if-field', function(){
			var $valP = $(this).closest('.wpps-bf-conditional-grid').find('.wpps-bf-conditional-value');
			var controlId = $valP.find('.field-show-if-value').attr('id') || '';
			$valP.find('.field-show-if-value').remove();
			// Reset the value when the controller changes — old values rarely match new options.
			$valP.append(conditionalValueControl($(this).val(), '', controlId));
		});

		$(document).on('change', '.field-show-if-operator', function(){
			var op = $(this).val();
			var valueless = op === 'empty' || op === 'not_empty';
			var $grid = $(this).closest('.wpps-bf-conditional-grid');
			$grid.toggleClass('is-value-hidden', valueless);
			$grid.find('.wpps-bf-conditional-value').toggleClass('is-hidden', valueless);
		});

		$(document).on('change', '.field-conditional-enable', function(){
			var enabled = $(this).is(':checked');
			var $wrap = $(this).closest('.wpps-bf-conditional-settings');
			$wrap.toggleClass('is-enabled', enabled);
			$wrap.find('.wpps-bf-conditional-body').prop('hidden', !enabled);
			var $item = $(this).closest('.wpps-bf-form-field-item');
			syncFieldFromDom($item, $item.data('id'));
			updateData();
		});

		$(document).on('click', '.wpps-bf-add-condition', function(e){
			e.preventDefault();
			var $item = $(this).closest('.wpps-bf-form-field-item');
			var id = $item.data('id');
			var otherFields = formFields.filter(function (x) {
				return x.id !== id && !isLayoutField(x.type) && x.field_id;
			});
			$(this).closest('.wpps-bf-conditional-body').find('.wpps-bf-conditional-rules').append(conditionalRuleRow(otherFields, {}));
			syncFieldFromDom($item, id);
			updateData();
		});

		$(document).on('click', '.wpps-bf-remove-condition', function(e){
			e.preventDefault();
			var $rule = $(this).closest('.wpps-bf-conditional-rule');
			var $rules = $rule.closest('.wpps-bf-conditional-rules');
			var $item = $(this).closest('.wpps-bf-form-field-item');
			var id = $item.data('id');
			if ($rules.find('.wpps-bf-conditional-rule').length > 1) {
				$rule.remove();
			} else {
				// Keep one row available; clear it instead of removing the last condition.
				$rule.find('.field-show-if-field').val('');
				$rule.find('.field-show-if-operator').val('equals');
				var $valP = $rule.find('.wpps-bf-conditional-value');
				$valP.find('.field-show-if-value').remove();
				$valP.append(conditionalValueControl('', '', ''));
				$rule.find('.wpps-bf-conditional-grid').removeClass('is-value-hidden');
				$valP.removeClass('is-hidden');
			}
			syncFieldFromDom($item, id);
			updateData();
		});

		$(document).on('click', '.duplicate-field', function(e){
			e.stopPropagation();
			var $item = $(this).closest('.wpps-bf-form-field-item');
			var id = $item.data('id');
			syncFieldFromDom($item, id);
			var f = formFields.find(function(x){ return x.id === id; });
			if (!f) return;
			var fid = fieldCounter++;
			var copy = JSON.parse(JSON.stringify(f));
			copy.id = fid;
			if (!isLayoutField(copy.type)) {
				copy.field_id = ensureUniqueFieldId(slugFromLabel(copy.label), fid);
			}
			var idx = formFields.findIndex(function(x){ return x.id === id; });
			formFields.splice(idx + 1, 0, copy);
			renderField(copy);
			var $new = $('#wpps-bf-fields-container .wpps-bf-form-field-item[data-id="' + fid + '"]');
			$new.insertAfter($item);
			if ($('#wpps-bf-fields-container').sortable('instance')) {
				$('#wpps-bf-fields-container').sortable('refresh');
			}
			updateData();
		});

		$(document).on('click', '.delete-field', function(e){
			e.stopPropagation();
			if (confirm('Delete this field?')) {
				var id = $(this).closest('.wpps-bf-form-field-item').data('id');
				formFields = formFields.filter(function(x){ return x.id !== id; });
				$(this).closest('.wpps-bf-form-field-item').remove();
				updateData();
			}
		});

		$('#wpps-bf-fields-container').sortable({
			handle: '.wpps-bf-field-drag',
			placeholder: 'wpps-bf-field-placeholder',
			axis: 'y',
			update: function() { reorder(); }
		});

		function reorder(){
			var order = [];
			$('#wpps-bf-fields-container .wpps-bf-form-field-item').each(function(){
				var id = $(this).data('id');
				var f = formFields.find(function(x){ return x.id === id; });
				if (f) order.push(f);
			});
			formFields = order;
			updateData();
		}

		$(document).on('input change', '.wpps-bf-field-body input, .wpps-bf-field-body select, .wpps-bf-field-body textarea', function(){
			var $item = $(this).closest('.wpps-bf-form-field-item');
			var id = $item.data('id');
			syncFieldFromDom($item, id);
			var f = formFields.find(function(x){ return x.id === id; });
			if (f) updateFieldHeader($item, f);
			updateData();
		});

		function updateData(){
			$('#wpps-bf-form-fields-data').val(JSON.stringify(formFields));
		}

		function syncAllFieldsFromDom() {
			$('#wpps-bf-fields-container .wpps-bf-form-field-item').each(function () {
				syncFieldFromDom($(this), $(this).data('id'));
			});
			updateData();
		}

		window.wppsBfGetFormSnapshot = function () {
			syncAllFieldsFromDom();
			var design = {};
			$('#wpps-bf-design-modal').find('[name^="form_design["]').each(function () {
				var $el = $(this);
				var name = $el.attr('name');
				var m = name && name.match(/^form_design\[([^\]]+)\]$/);
				if (!m) {
					return;
				}
				if ($el.is(':checkbox')) {
					design[m[1]] = $el.is(':checked') ? '1' : '';
				} else {
					design[m[1]] = $el.val() || '';
				}
			});
			return {
				title: ($('#wpps-bf-form-title').val() || '').trim(),
				form_id: parseInt($('input[name="wpps_bf_form_id"]').val(), 10) || 0,
				fields: JSON.parse(JSON.stringify(formFields)),
				settings: {
					subject: $('#wpps-bf-subject').val() || '',
					success_message: $('#wpps-bf-success-message').val() || '',
					submit_button_text: $('#wpps-bf-submit-text').val() || '',
					redirect_url: $('#wpps-bf-redirect').val() || '',
					enable_autoreply: $('#wpps-bf-enable-autoreply').is(':checked') ? '1' : '',
					autoreply_subject: $('#wpps-bf-autoreply-subject').val() || '',
					autoreply_message: $('#wpps-bf-autoreply-message').val() || ''
				},
				design: design
			};
		};

		window.wppsBfApplyAiPayload = function (payload, intent) {
			intent = intent || 'modify';
			if (!payload || !Array.isArray(payload.fields)) {
				return;
			}

			if (intent === 'add_fields') {
				payload.fields.forEach(function (f) {
					var fid = fieldCounter++;
					f.id = fid;
					if (f.type !== 'separator' && f.type !== 'group' && f.type !== 'html' && !f.field_id) {
						f.field_id = ensureUniqueFieldId(slugFromLabel(f.label), fid);
					}
					formFields.push(f);
					renderField(f);
				});
				if ($('#wpps-bf-fields-container').sortable('instance')) {
					$('#wpps-bf-fields-container').sortable('refresh');
				}
				updateData();
				return;
			}

			$('#wpps-bf-fields-container').empty();
			formFields = payload.fields;
			fieldCounter = 0;
			formFields.forEach(function (f) {
				if (f.type !== 'separator' && f.type !== 'group' && f.type !== 'html' && !f.field_id) {
					f.field_id = ensureUniqueFieldId(slugFromLabel(f.label), f.id);
				}
				renderField(f);
				if (f.id >= fieldCounter) {
					fieldCounter = f.id + 1;
				}
			});
			if ($('#wpps-bf-fields-container').sortable('instance')) {
				$('#wpps-bf-fields-container').sortable('refresh');
			}
			updateData();
		};

		$('#wpps-bf-editor-form').on('submit', function () {
			syncAllFieldsFromDom();
		});
	});
})(jQuery);
