/**
 * SiteStaffr Widget Settings - Live Preview
 *
 * Provides real-time preview of widget appearance as admin changes settings.
 *
 * @link       https://github.com/sitestaffr/sitestaffr-plugin
 * @since      0.11.95
 *
 * @package    SiteStaffr
 * @subpackage SiteStaffr/assets/js
 */

(function($) {
	'use strict';

	/**
	 * Initialize live preview functionality when DOM is ready.
	 */
	$(document).ready(function() {
		// Initialize color pickers
		initColorPickers();

		// Initialize border radius lock/unlock controls
		initRadiusControls();

		// Initialize live previews
		initFixedWidgetPreview();
		initButtonWidgetPreview();

		// Watch for settings changes
		watchFixedWidgetSettings();
		watchButtonWidgetSettings();

		// Initialize copy buttons
		initCopyButtons();

		// Initialize voice preview buttons
		initVoicePreviewButtons();

		// Initialize per-section AJAX save buttons
		initSectionSave();

		// Presets row + brand color + reset-to-preset
		initPresets();

		// Preview backdrop toggle (light / dark / custom)
		initPreviewBackdrops();

		// Border-dependent field visibility (tabs = shared component)
		toggleBorderDependents('fixed');
		toggleBorderDependents('button');

	});

	// =========================================================================
	// STYLE PRESETS — one click sets shape/style fields; brand color drives the
	// palette. Presets pre-fill the Advanced fields; values stay the source of
	// truth (saving works exactly as before).
	// =========================================================================

	var WS_PRESETS = {
		fixed: {
			round:   { outline: false, fields: { fixed_border_radius_locked: true, fixed_border_radius_top: 200, fixed_border_radius_right: 200, fixed_border_radius_bottom: 200, fixed_border_radius_left: 200, fixed_border_style: 'none', fixed_border_width: 0 } },
			soft:    { outline: false, fields: { fixed_border_radius_locked: false, fixed_border_radius_top: 20, fixed_border_radius_right: 20, fixed_border_radius_bottom: 20, fixed_border_radius_left: 0, fixed_border_style: 'none', fixed_border_width: 0 } },
			rounded: { outline: false, fields: { fixed_border_radius_locked: true, fixed_border_radius_top: 16, fixed_border_radius_right: 16, fixed_border_radius_bottom: 16, fixed_border_radius_left: 16, fixed_border_style: 'none', fixed_border_width: 0 } },
			square:  { outline: false, fields: { fixed_border_radius_locked: true, fixed_border_radius_top: 4, fixed_border_radius_right: 4, fixed_border_radius_bottom: 4, fixed_border_radius_left: 4, fixed_border_style: 'none', fixed_border_width: 0 } },
			outline: { outline: true,  fields: { fixed_border_radius_locked: true, fixed_border_radius_top: 200, fixed_border_radius_right: 200, fixed_border_radius_bottom: 200, fixed_border_radius_left: 200, fixed_border_style: 'solid', fixed_border_width: 2 } }
		},
		button: {
			pill:     { outline: false, fields: { button_border_radius_locked: true, button_border_radius_top: 80, button_border_radius_right: 80, button_border_radius_bottom: 80, button_border_radius_left: 80, button_border_style: 'none', button_border_width: 0, button_gradient: false, button_box_shadow: true } },
			gradient: { outline: false, fields: { button_border_radius_locked: true, button_border_radius_top: 80, button_border_radius_right: 80, button_border_radius_bottom: 80, button_border_radius_left: 80, button_border_style: 'none', button_border_width: 0, button_gradient: true, button_box_shadow: true } },
			rounded:  { outline: false, fields: { button_border_radius_locked: true, button_border_radius_top: 12, button_border_radius_right: 12, button_border_radius_bottom: 12, button_border_radius_left: 12, button_border_style: 'none', button_border_width: 0, button_gradient: false, button_box_shadow: true } },
			square:   { outline: false, fields: { button_border_radius_locked: true, button_border_radius_top: 4, button_border_radius_right: 4, button_border_radius_bottom: 4, button_border_radius_left: 4, button_border_style: 'none', button_border_width: 0, button_gradient: false, button_box_shadow: false } },
			outline:  { outline: true,  fields: { button_border_radius_locked: true, button_border_radius_top: 12, button_border_radius_right: 12, button_border_radius_bottom: 12, button_border_radius_left: 12, button_border_style: 'solid', button_border_width: 2, button_gradient: false, button_box_shadow: false } }
		}
	};

	var WS_DEFAULT_PRESET = { fixed: 'soft', button: 'pill' };

	/** The stock brand color, declared once in the markup (data-default-color). */
	function defaultBrandColor(section) {
		return $('#' + section + '_brand_color').data('default-color');
	}

	/** Darken a #rrggbb color by a 0-1 amount (returns input when not hex). */
	function darkenHex(hex, amount) {
		var m = /^#?([0-9a-f]{6})$/i.exec(String(hex).trim());
		if (!m) return hex;
		var num = parseInt(m[1], 16);
		var r = Math.round(((num >> 16) & 255) * (1 - amount));
		var g = Math.round(((num >> 8) & 255) * (1 - amount));
		var b = Math.round((num & 255) * (1 - amount));
		return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
	}

	/** Set a color field through iris so its change pipeline (preview + dirty) runs. */
	function setColorField(id, value) {
		var $field = $('#' + id);
		if (!$field.length) return;
		if ($.fn.wpColorPicker && $field.closest('.wp-picker-container').length) {
			$field.wpColorPicker('color', value);
		} else {
			$field.val(value).trigger('change');
		}
	}

	/** Apply the brand color across a section's color fields (preset-aware). */
	function applyBrandColor(section, color) {
		var presetName = $('#' + section + '_preset').val();
		var preset = (WS_PRESETS[section] || {})[presetName];
		var isOutline = !!(preset && preset.outline);
		var hover = darkenHex(color, 0.15);

		if (section === 'fixed') {
			if (isOutline) {
				setColorField('fixed_background_color', '#ffffff');
				setColorField('fixed_hover_background_color', '#f2f2f2');
				setColorField('fixed_icon_color', color);
				setColorField('fixed_hover_icon_color', hover);
				setColorField('fixed_border_color', color);
			} else {
				setColorField('fixed_background_color', color);
				setColorField('fixed_hover_background_color', hover);
				setColorField('fixed_icon_color', '#ffffff');
				setColorField('fixed_border_color', color);
			}
		} else {
			if (isOutline) {
				setColorField('button_background_color', '#ffffff');
				setColorField('button_hover_background', '#f2f2f2');
				setColorField('button_text_color', color);
				setColorField('button_icon_color', color);
				setColorField('button_border_color', color);
			} else {
				setColorField('button_background_color', color);
				setColorField('button_hover_background', hover);
				setColorField('button_text_color', '#ffffff');
				setColorField('button_icon_color', '#ffffff');
				setColorField('button_border_color', color);
				setColorField('button_gradient_end', darkenHex(color, 0.3));
			}
		}
	}

	/** Apply a preset's fields, recolor from the brand picker, and pulse the preview. */
	function applyPreset(section, name) {
		var preset = (WS_PRESETS[section] || {})[name];
		if (!preset) return;

		$('#' + section + '_preset').val(name);

		Object.keys(preset.fields).forEach(function(fieldId) {
			var value = preset.fields[fieldId];
			var $field = $('#' + fieldId);
			if (!$field.length) return;
			if ($field.is(':checkbox')) {
				$field.prop('checked', !!value).trigger('change');
			} else {
				$field.val(value).trigger('change');
			}
		});

		applyBrandColor(section, $('#' + section + '_brand_color').val() || defaultBrandColor(section));

		var $cards = $('.sitestaffr-ws-presets[data-preset-section="' + section + '"] .sitestaffr-ws-preset-card');
		$cards.removeClass('is-active').filter('[data-preset="' + name + '"]').addClass('is-active');
		$('.sitestaffr-ws-reset-preset[data-preset-section="' + section + '"]').prop('disabled', false);

		markSectionDirty($('#' + section + '_preset'));

		// Animate the change so the preview visibly responds.
		var previewId = section === 'fixed' ? '#sitestaffr-fixed-widget-preview' : '#sitestaffr-button-widget-preview';
		var $preview = $(previewId);
		$preview.addClass('sitestaffr-ws-preview-animate');
		setTimeout(function() { $preview.removeClass('sitestaffr-ws-preview-animate'); }, 450);
	}

	function initPresets() {
		$('.sitestaffr-ws-preset-card').on('click', function() {
			var section = $(this).closest('.sitestaffr-ws-presets').data('preset-section');
			applyPreset(section, $(this).data('preset'));
		});

		// Reset restores the preset's stock look — brand color included, so a widget
		// whose saved colors have drifted goes back to a known-good state in one click.
		$('.sitestaffr-ws-reset-preset').on('click', function() {
			var section = $(this).data('preset-section');
			var current = $('#' + section + '_preset').val() || WS_DEFAULT_PRESET[section];
			setColorField(section + '_brand_color', defaultBrandColor(section));
			applyPreset(section, current);
		});
	}

	// =========================================================================
	// PREVIEW BACKDROPS — light / dark / custom, per preview column.
	// =========================================================================

	function initPreviewBackdrops() {
		$('.sitestaffr-ws-backdrop-btn').on('click', function() {
			var $col = $(this).closest('.sitestaffr-ws-preview-col');
			$(this).addClass('is-active').siblings('.sitestaffr-ws-backdrop-btn').removeClass('is-active');
			$col.toggleClass('is-dark-backdrop', $(this).data('backdrop') === 'dark');
			$col.css('--ws-backdrop', '');
		});

		$('.sitestaffr-ws-backdrop-color').on('input change', function() {
			var $col = $(this).closest('.sitestaffr-ws-preview-col');
			$col.removeClass('is-dark-backdrop');
			$col.find('.sitestaffr-ws-backdrop-btn').removeClass('is-active');
			$col.css('--ws-backdrop', $(this).val());
		});
	}

	// Per-section dirty trackers (populated in initSectionSave); the color
	// picker commits values via .val() with no event, so its callbacks mark
	// the section dirty explicitly.
	var sectionDirty = {};

	function markSectionDirty(target) {
		var section = $(target).closest('.sitestaffr-ws-section').data('section');
		if (sectionDirty[section]) {
			sectionDirty[section].markDirty();
		}
	}

	/**
	 * Initialize WordPress color pickers.
	 */
	function initColorPickers() {
		if ($.fn.wpColorPicker) {
			$('.sitestaffr-color-field').wpColorPicker({
				change: function(event, ui) {
					// wpColorPicker can fire before the input value is committed.
					// Apply the UI value first, then update preview on next frame.
					if (ui && ui.color) {
						$(event.target).val(ui.color.toString());
					}
					// Brand color fans out across the section's color fields.
					if ($(event.target).hasClass('sitestaffr-ws-brand-color') && ui && ui.color) {
						applyBrandColor($(event.target).data('brand-section'), ui.color.toString());
					}
					markSectionDirty(event.target);
					window.requestAnimationFrame(function() {
						updateFixedWidgetPreview();
						updateButtonWidgetPreview();
					});
				},
				clear: function(event) {
					markSectionDirty(event.target);
					window.requestAnimationFrame(function() {
						updateFixedWidgetPreview();
						updateButtonWidgetPreview();
					});
				}
			});
		}
	}

	/**
	 * Get fixed widget icon SVG markup for the admin preview.
	 *
	 * @param {string} icon - Icon type: 'phone', 'microphone', 'chat', 'headset'.
	 * @returns {string} SVG markup string.
	 */
	function getFixedIconSVG(icon) {
		if (icon === 'sitestaffr' && sitestaffr_admin_data.sitestaffr_icon_svg) {
			// Replace outer SVG tag with widget-preview attributes
			return sitestaffr_admin_data.sitestaffr_icon_svg.replace(
				/<svg[^>]*>/,
				'<svg class="sitestaffr-widget-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="74 104 412 412" fill="currentColor" stroke="none" aria-hidden="true">'
			);
		}
		const svgs = {
			'phone': '<svg class="sitestaffr-widget-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>',
			'microphone': '<svg class="sitestaffr-widget-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>',
			'chat': '<svg class="sitestaffr-widget-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>',
			'headset': '<svg class="sitestaffr-widget-icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path></svg>'
		};
		return svgs[icon] || getFixedIconSVG('sitestaffr');
	}

	/**
	 * Initialize fixed widget preview.
	 */
	function initFixedWidgetPreview() {
		const preview = $('#sitestaffr-fixed-widget-preview');
		if (preview.length === 0) return;

		const icon = $('#fixed_icon').val() || 'sitestaffr';

		// Create preview HTML using the selected icon
		const previewHTML = `
			<div class="sitestaffr-preview-widget-container">
				<div class="sitestaffr-preview-scene">
					<div class="sitestaffr-preview-widget" id="sitestaffr-preview-fixed">
						<button type="button" class="sitestaffr-widget-trigger" aria-label="Talk to us">
							${getFixedIconSVG(icon)}
						</button>
					</div>
				</div>
			</div>
		`;

		preview.html(previewHTML);
		updateFixedWidgetPreview();
	}

	/**
	 * Initialize button widget preview.
	 */
	function initButtonWidgetPreview() {
		const preview = $('#sitestaffr-button-widget-preview');
		if (preview.length === 0) return;

		// Create preview HTML with initial icon
		updateButtonWidgetPreview();
	}

	/**
	 * Watch for fixed widget settings changes.
	 */
	function watchFixedWidgetSettings() {
		// Icon type
		$('#fixed_icon').on('change', updateFixedWidgetPreview);

		// Background color
		$('#fixed_background_color').on('change', updateFixedWidgetPreview);

		// Icon color
		$('#fixed_icon_color').on('change', updateFixedWidgetPreview);

		// Icon size
		$('#fixed_icon_size').on('input change', updateFixedWidgetPreview);

		// Hover background color
		$('#fixed_hover_background_color').on('change', updateFixedWidgetPreview);

		// Hover icon color
		$('#fixed_hover_icon_color').on('change', updateFixedWidgetPreview);

		// Tooltip
		$('#fixed_tooltip_text').on('input', updateFixedWidgetPreview);
		$('#fixed_tooltip_behavior').on('change', function() {
			$('#sitestaffr-ws-tooltip-fields').toggle($(this).val() !== 'off');
			updateFixedWidgetPreview();
		});
		$('#fixed_tooltip_position').on('change', updateFixedWidgetPreview);

		// Size
		$('#fixed_size').on('input change', updateFixedWidgetPreview);

		// Border radius
		$('#fixed_border_radius_locked').on('change', updateFixedWidgetPreview);
		$('#fixed_border_radius_top, #fixed_border_radius_right, #fixed_border_radius_bottom, #fixed_border_radius_left')
			.on('input change', updateFixedWidgetPreview);

		// Border style, width, color
		$('#fixed_border_style').on('change', function() {
			toggleBorderDependents('fixed');
			updateFixedWidgetPreview();
		});
		$('#fixed_border_width').on('input change', updateFixedWidgetPreview);
		$('#fixed_border_color').on('change', updateFixedWidgetPreview);
	}

	/**
	 * Update fixed widget preview.
	 */
	/**
	 * Ensure a CSS value has 'px' units. Handles both '60' and '60px' inputs.
	 */
	function ensurePx(val, fallback) {
		if (!val && val !== 0) return fallback;
		val = String(val).trim();
		if (val === '') return fallback;
		// Already has units? Return as-is.
		if (/[a-z%]$/i.test(val)) return val;
		return val + 'px';
	}

	/**
	 * Toggle visibility of border width/color fields based on border style.
	 */
	function toggleBorderDependents(section) {
		var style = $('#' + section + '_border_style').val();
		$('.sitestaffr-ws-border-dependent[data-border-section="' + section + '"]').toggleClass('is-hidden', style === 'none');
	}

	/**
	 * Initialize lock/unlock toggles for border radius controls.
	 */
	function initRadiusControls() {
		['fixed', 'button'].forEach(function(prefix) {
			const lockInput = $('#' + prefix + '_border_radius_locked');
			if (lockInput.length === 0) {
				return;
			}

			const topInput = $('#' + prefix + '_border_radius_top');
			const rightInput = $('#' + prefix + '_border_radius_right');
			const bottomInput = $('#' + prefix + '_border_radius_bottom');
			const leftInput = $('#' + prefix + '_border_radius_left');
			const linkedInputs = rightInput.add(bottomInput).add(leftInput);

			function syncLockedValues() {
				const topValue = topInput.val();
				linkedInputs.val(topValue);
			}

			function applyLockState(syncOnLock) {
				const locked = lockInput.is(':checked');
				const group = $('[data-radius-group="' + prefix + '"]');
				const lockIcon = $('[data-radius-lock-icon="' + prefix + '"]');
				const lockToggle = $('[data-radius-lock-toggle="' + prefix + '"]');

				group.toggleClass('is-locked', locked);
				linkedInputs.prop('disabled', locked);
				lockIcon.toggleClass('dashicons-lock', locked);
				lockIcon.toggleClass('dashicons-unlock', !locked);
				lockToggle.toggleClass('is-locked', locked);
				lockToggle.attr('title', locked ? 'Unlock corners' : 'Lock all corners');

				if (locked && syncOnLock) {
					syncLockedValues();
				}
			}

			lockInput.on('change', function() {
				applyLockState(true);
				if (prefix === 'fixed') {
					updateFixedWidgetPreview();
				} else {
					updateButtonWidgetPreview();
				}
			});

			topInput.on('input change', function() {
				if (lockInput.is(':checked')) {
					syncLockedValues();
				}
			});

			applyLockState(lockInput.is(':checked'));
		});
	}

	/**
	 * Build border-radius shorthand from per-side inputs.
	 */
	function getBorderRadiusValue(prefix, defaults) {
		const top = ensurePx($('#' + prefix + '_border_radius_top').val(), defaults.top);
		const right = ensurePx($('#' + prefix + '_border_radius_right').val(), defaults.right);
		const bottom = ensurePx($('#' + prefix + '_border_radius_bottom').val(), defaults.bottom);
		const left = ensurePx($('#' + prefix + '_border_radius_left').val(), defaults.left);

		if ($('#' + prefix + '_border_radius_locked').is(':checked')) {
			return [top, top, top, top].join(' ');
		}

		return [top, right, bottom, left].join(' ');
	}

	function updateFixedWidgetPreview() {
		const widget = $('#sitestaffr-preview-fixed');
		if (widget.length === 0) return;

		const backgroundColor = $('#fixed_background_color').val() || '#10b981';
		const hoverBackgroundColor = $('#fixed_hover_background_color').val() || backgroundColor;
		const iconColor = $('#fixed_icon_color').val() || '#ffffff';
		const hoverIconColor = $('#fixed_hover_icon_color').val() || iconColor;
		const size = ensurePx($('#fixed_size').val(), '60px');
		const iconSize = ensurePx($('#fixed_icon_size').val(), '24px');
		const icon = $('#fixed_icon').val() || 'sitestaffr';
		const borderRadius = getBorderRadiusValue('fixed', {
			top: '20px',
			right: '20px',
			bottom: '20px',
			left: '0px'
		});
		const fixedBorderStyle = $('#fixed_border_style').val() || 'none';
		const fixedBorderWidth = ensurePx($('#fixed_border_width').val(), '0px');
		const fixedBorderColor = $('#fixed_border_color').val() || '#cccccc';
		const tooltipText = $('#fixed_tooltip_text').val() || 'Talk to AI Assistant';
		const tooltipBehavior = $('#fixed_tooltip_behavior').val() || 'auto';

		// Swap icon SVG based on selected type
		widget.find('.sitestaffr-widget-trigger').html(getFixedIconSVG(icon));

		// Update button styles
		const button = widget.find('.sitestaffr-widget-trigger');
		button.css({
			'background-color': backgroundColor,
			'width': size,
			'height': size,
			'color': iconColor,
			'border-radius': borderRadius,
			'border': fixedBorderStyle !== 'none' && fixedBorderWidth !== '0px' && fixedBorderWidth !== '0'
				? fixedBorderWidth + ' ' + fixedBorderStyle + ' ' + fixedBorderColor
				: 'none'
		});

		// Update icon size
		widget.find('.sitestaffr-widget-icon').css({
			'width': iconSize,
			'height': iconSize
		});

		// Apply hover color preview (background + icon)
		button.off('mouseenter.preview mouseleave.preview');
		button.on('mouseenter.preview', function() {
			$(this).css({ 'background-color': hoverBackgroundColor, 'color': hoverIconColor });
			$(this).find('.sitestaffr-widget-icon').css('color', hoverIconColor);
		}).on('mouseleave.preview', function() {
			$(this).css({ 'background-color': backgroundColor, 'color': iconColor });
			$(this).find('.sitestaffr-widget-icon').css('color', iconColor);
		});

		// Update icon color — set both wrapper and SVG for consistent inheritance.
		widget.find('.sitestaffr-widget-icon').css('color', iconColor);

		// Tooltip preview — mode-aware behavior
		const tooltipPosition = $('#fixed_tooltip_position').val() || 'top';
		let tooltipEl = widget.find('.sitestaffr-preview-tooltip');
		if (tooltipEl.length === 0) {
			widget.append('<div class="sitestaffr-preview-tooltip"></div>');
			tooltipEl = widget.find('.sitestaffr-preview-tooltip');
		}
		tooltipEl.text(tooltipText);
		tooltipEl.stop(true, true).css('opacity', '');
		button.off('mouseenter.tooltip mouseleave.tooltip');

		if (tooltipBehavior === 'off') {
			tooltipEl.hide();
		} else if (tooltipBehavior === 'always') {
			tooltipEl.show().css('opacity', '1');
		} else if (tooltipBehavior === 'hover') {
			tooltipEl.hide();
			button.on('mouseenter.tooltip', function() {
				tooltipEl.stop(true, true).show().animate({ opacity: 1 }, 200);
			}).on('mouseleave.tooltip', function() {
				tooltipEl.stop(true, true).animate({ opacity: 0 }, 200, function() { $(this).hide(); });
			});
		} else if (tooltipBehavior === 'auto') {
			tooltipEl.show().css('opacity', '1');
			tooltipEl.stop(true, true)
				.delay(3000).animate({ opacity: 0 }, 400, function() {
					button.on('mouseenter.tooltip', function() {
						tooltipEl.stop(true, true).show().animate({ opacity: 1 }, 200);
					}).on('mouseleave.tooltip', function() {
						tooltipEl.stop(true, true).animate({ opacity: 0 }, 200);
					});
				});
		}

		// Position tooltip above or below the button
		if (tooltipPosition === 'bottom') {
			tooltipEl.css({ 'bottom': 'auto', 'top': 'calc(100% + 8px)' });
		} else {
			tooltipEl.css({ 'top': '', 'bottom': 'calc(100% + 8px)' });
		}
	}

	/**
	 * Watch for button widget settings changes.
	 */
	function watchButtonWidgetSettings() {
		// Text
		$('#button_text').on('input', updateButtonWidgetPreview);
		$('#button_font_size').on('input change', updateButtonWidgetPreview);
		$('#button_font_weight').on('change', updateButtonWidgetPreview);
		$('#button_text_color').on('change', updateButtonWidgetPreview);
		$('#button_text_transform').on('change', updateButtonWidgetPreview);

		// Background
		$('#button_background_color').on('change', updateButtonWidgetPreview);
		$('#button_hover_background').on('change', updateButtonWidgetPreview);
		$('#button_gradient').on('change', updateButtonWidgetPreview);
		$('#button_gradient_end').on('change', updateButtonWidgetPreview);

		// Border
		$('#button_border_radius_locked').on('change', updateButtonWidgetPreview);
		$('#button_border_radius_top, #button_border_radius_right, #button_border_radius_bottom, #button_border_radius_left')
			.on('input change', updateButtonWidgetPreview);
		$('#button_border_width').on('input change', updateButtonWidgetPreview);
		$('#button_border_color').on('change', updateButtonWidgetPreview);
		$('#button_border_style').on('change', function() {
			toggleBorderDependents('button');
			updateButtonWidgetPreview();
		});

		// Shadow
		$('#button_box_shadow').on('change', updateButtonWidgetPreview);
		$('#button_shadow_color').on('input change', updateButtonWidgetPreview);
		$('#button_shadow_blur').on('input change', updateButtonWidgetPreview);
		$('#button_shadow_offset').on('input change', updateButtonWidgetPreview);

		// Size
		$('#button_padding_x').on('input change', updateButtonWidgetPreview);
		$('#button_padding_y').on('input change', updateButtonWidgetPreview);
		$('#button_full_width').on('change', updateButtonWidgetPreview);

		// Icon
		$('#button_icon').on('change', updateButtonWidgetPreview);
		$('#button_icon_position').on('change', updateButtonWidgetPreview);
		$('#button_icon_size').on('input change', updateButtonWidgetPreview);
		$('#button_icon_color').on('change', updateButtonWidgetPreview);

		// Hover animation
		$('#button_hover_animation').on('change', updateButtonWidgetPreview);

		// Listening state
		$('#button_listening_text').on('input', updateButtonWidgetPreview);
		$('#button_listening_color').on('change', updateButtonWidgetPreview);
	}

	/**
	 * Get icon SVG markup.
	 */
	function getIconSVG(icon, size) {
		if (icon === 'sitestaffr' && sitestaffr_admin_data.sitestaffr_icon_svg) {
			return sitestaffr_admin_data.sitestaffr_icon_svg.replace(
				/<svg[^>]*>/,
				'<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" viewBox="74 104 412 412" fill="currentColor" stroke="none" aria-hidden="true">'
			);
		}
		const svgs = {
			'microphone': '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line></svg>',
			'phone': '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path></svg>',
			'chat': '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg>',
			'headset': '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + size + '" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path></svg>',
			'none': ''
		};

		return svgs[icon] || getIconSVG('sitestaffr', size);
	}

	/**
	 * Update button widget preview.
	 */
	function updateButtonWidgetPreview() {
		const preview = $('#sitestaffr-button-widget-preview');
		if (preview.length === 0) return;

		// Get all settings (ensurePx for numeric inputs that need CSS units)
		const text = $('#button_text').val() || 'Contact Us';
		const fontSize = ensurePx($('#button_font_size').val(), '16px');
		const fontWeight = $('#button_font_weight').val() || '600';
		const textColor = $('#button_text_color').val() || '#ffffff';
		const textTransform = $('#button_text_transform').val() || 'none';
		const backgroundColor = $('#button_background_color').val() || '#1FB6CC';
		const gradient = $('#button_gradient').is(':checked');
		const gradientEnd = $('#button_gradient_end').val() || '#10b981';
		const borderRadius = getBorderRadiusValue('button', {
			top: '80px',
			right: '80px',
			bottom: '80px',
			left: '80px'
		});
		const borderWidth = ensurePx($('#button_border_width').val(), '0px');
		const borderColor = $('#button_border_color').val() || '#1FB6CC';
		const borderStyle = $('#button_border_style').val() || 'solid';
		const boxShadow = $('#button_box_shadow').is(':checked');
		const shadowColor = $('#button_shadow_color').val() || 'rgba(0,0,0,0.2)';
		const shadowBlur = ensurePx($('#button_shadow_blur').val(), '10px');
		const shadowOffset = ensurePx($('#button_shadow_offset').val(), '4px');
		const paddingX = ensurePx($('#button_padding_x').val(), '24px');
		const paddingY = ensurePx($('#button_padding_y').val(), '12px');
		const fullWidth = $('#button_full_width').is(':checked');
		const icon = $('#button_icon').val() || 'phone';
		const iconPosition = $('#button_icon_position').val() || 'left';
		const iconSize = ensurePx($('#button_icon_size').val(), '18px');
		const iconColor = $('#button_icon_color').val() || textColor;

		// Build background style
		let background;
		if (gradient && gradientEnd) {
			background = 'linear-gradient(135deg, ' + backgroundColor + ' 0%, ' + gradientEnd + ' 100%)';
		} else {
			background = backgroundColor;
		}

		// Build box shadow style
		let shadow = 'none';
		if (boxShadow) {
			shadow = '0 ' + shadowOffset + ' ' + shadowBlur + ' ' + shadowColor;
		}

		// Build border style
		let border = 'none';
		if (borderStyle !== 'none' && borderWidth !== '0px' && borderWidth !== '0') {
			border = borderWidth + ' ' + borderStyle + ' ' + borderColor;
		}

		// Build button styles
		const buttonStyles = {
			'color': textColor,
			'font-size': fontSize,
			'font-weight': fontWeight,
			'text-transform': textTransform,
			'background': background,
			'border-radius': borderRadius,
			'border': border,
			'box-shadow': shadow,
			'padding': paddingY + ' ' + paddingX,
			'display': 'inline-flex',
			'align-items': 'center',
			'gap': '8px',
			'cursor': 'pointer',
			'transition': 'all 0.3s ease',
			'width': fullWidth ? '100%' : 'auto',
			'justify-content': 'center'
		};

		// Get icon SVG
		const iconSVG = getIconSVG(icon, iconSize);

		// Build button HTML
		let buttonHTML = '<button type="button" class="sitestaffr-button-preview" style="' +
			Object.entries(buttonStyles).map(([key, value]) => key + ': ' + value).join('; ') +
			'">';

		if (icon !== 'none' && iconPosition === 'left') {
			buttonHTML += '<span class="sitestaffr-button-icon" style="color: ' + iconColor + ';">' + iconSVG + '</span>';
		}

		buttonHTML += '<span class="sitestaffr-button-text">' + text + '</span>';

		if (icon !== 'none' && iconPosition === 'right') {
			buttonHTML += '<span class="sitestaffr-button-icon" style="color: ' + iconColor + ';">' + iconSVG + '</span>';
		}

		buttonHTML += '</button>';

		// Update preview
		preview.html('<div class="sitestaffr-button-preview-container">' + buttonHTML + '</div>');

		// Apply hover animation preview
		var hoverAnimation = $('#button_hover_animation').val() || 'none';
		var hoverBg = $('#button_hover_background').val() || '#005a87';
		var $btn = preview.find('.sitestaffr-button-preview');

		$btn.on('mouseenter', function() {
			var $this = $(this);
			$this.data('orig-bg', $this.css('background'));
			// Apply hover background (use inline so gradient buttons get solid hover)
			$this.css('background', hoverBg);
			if (hoverAnimation === 'scale') {
				$this.css('transform', 'scale(1.05)');
			} else if (hoverAnimation === 'glow') {
				$this.css('box-shadow', '0 0 20px ' + (backgroundColor || '#0073aa'));
			} else if (hoverAnimation === 'pulse') {
				$this.addClass('sitestaffr-ws-preview-pulse');
			}
		}).on('mouseleave', function() {
			var $this = $(this);
			$this.css({
				'background': $this.data('orig-bg'),
				'transform': '',
				'box-shadow': boxShadow ? '0 ' + shadowOffset + ' ' + shadowBlur + ' ' + shadowColor : 'none'
			}).removeClass('sitestaffr-ws-preview-pulse');
		});
	}

	/**
	 * Initialize click-to-copy shortcodes in section headers.
	 */
	function initCopyButtons() {
		$('.sitestaffr-ws-shortcode-click').on('click', function() {
			var $code = $(this);
			var shortcode = $code.data('shortcode');
			var originalText = $code.text();

			if (navigator.clipboard && navigator.clipboard.writeText) {
				navigator.clipboard.writeText(shortcode).then(function() {
					showCopiedFeedback($code, originalText);
				}).catch(function() {
					copyToClipboardFallback(shortcode, $code, originalText);
				});
			} else {
				copyToClipboardFallback(shortcode, $code, originalText);
			}
		});
	}

	/**
	 * Show copied feedback on shortcode element.
	 */
	function showCopiedFeedback($el, originalText) {
		$el.text('Copied!').addClass('copied');
		setTimeout(function() {
			$el.text(originalText).removeClass('copied');
		}, 1500);
	}

	/**
	 * Fallback method to copy text to clipboard.
	 */
	function copyToClipboardFallback(text, $el, originalText) {
		var textarea = document.createElement('textarea');
		textarea.value = text;
		textarea.style.position = 'fixed';
		textarea.style.opacity = '0';
		document.body.appendChild(textarea);
		textarea.select();

		try {
			document.execCommand('copy');
			showCopiedFeedback($el, originalText);
		} catch (err) {
			console.error('Failed to copy shortcode:', err);
		}

		document.body.removeChild(textarea);
	}

	// Tab behavior lives in the shared SiteStaffrTabs component
	// (admin/js/sitestaffr-tabs.js) — each tablist carries data-tab-storage.

	/**
	 * Per-section AJAX save (no page reload).
	 */
	function initSectionSave() {
		$('.sitestaffr-ws-save-btn').each(function() {
			var $btn = $(this);
			var section = $btn.data('section');
			var $section = $('.sitestaffr-ws-section[data-section="' + section + '"]');
			// Unsaved-changes guard per section, cleared on successful save.
			var dirty = SiteStaffrSaveUX.trackDirty($section);
			sectionDirty[section] = dirty;
			var status = SiteStaffrSaveUX.status($btn.siblings('.sitestaffr-ws-save-status'));

			$btn.on('click', function() {
				// Collect all input/select/textarea values within this section
				var settings = {};
				$section.find('[name^="sitestaffr_widget_settings["]').each(function() {
					var name = $(this).attr('name');
					var key = name.replace('sitestaffr_widget_settings[', '').replace(']', '');
					if ($(this).is(':checkbox')) {
						settings[key] = $(this).is(':checked') ? '1' : '';
					} else {
						settings[key] = $(this).val();
					}
				});

				// Also collect color picker values (they use hidden inputs)
				$section.find('.sitestaffr-color-field').each(function() {
					var name = $(this).attr('name');
					if (name) {
						var key = name.replace('sitestaffr_widget_settings[', '').replace(']', '');
						settings[key] = $(this).val();
					}
				});

				$btn.prop('disabled', true);
				status.saving();

				$.post(ajaxurl, {
					action: 'sitestaffr_save_widget_section',
					nonce: sitestaffr_admin_data.save_widget_nonce,
					section: section,
					settings: settings
				}).done(function(response) {
					if (response.success) {
						status.saved();
						dirty.markClean();
					} else {
						status.error();
					}
				}).fail(function() {
					status.error();
				}).always(function() {
					$btn.prop('disabled', false);
				});
			});
		});
	}

	/**
	 * Initialize voice preview buttons.
	 */
	function initVoicePreviewButtons() {
		// Store reference to currently playing audio
		let currentAudio = null;
		let isLoading = false;

		// Compact voice preview button (in header)
		$('#voice-preview-btn-compact').on('click', function(e) {
			e.preventDefault();

			const button = $(this);
			const voice = $('#ai_voice').val();

			// If loading, ignore clicks
			if (isLoading) return;

			// Stop any currently playing audio
			if (currentAudio) {
				currentAudio.pause();
				currentAudio = null;
				button.removeClass('playing');
				button.find('.dashicons').removeClass('dashicons-controls-pause dashicons-update').addClass('dashicons-controls-play');
				return;
			}

			// Show loading state
			isLoading = true;
			button.find('.dashicons').removeClass('dashicons-controls-play').addClass('dashicons-update spin');

			// Use static voice sample files (bundled with plugin)
			// Add version parameter to prevent caching issues
			const audioUrl = sitestaffr_admin_data.plugin_url + 'assets/audio/voice-samples/' + voice + '.mp3?v=' + sitestaffr_admin_data.version;

			// Create and play audio
			const audio = new Audio(audioUrl);
			currentAudio = audio;

			// Set up event handlers
			audio.addEventListener('canplaythrough', function() {
				isLoading = false;
				button.addClass('playing');
				button.find('.dashicons').removeClass('dashicons-update spin').addClass('dashicons-controls-pause');
				audio.play().catch(function(error) {
					console.error('SiteStaffr: Error playing audio:', error);
					resetButton();
				});
			}, { once: true });

			audio.addEventListener('ended', function() {
				resetButton();
			});

			audio.addEventListener('error', function(e) {
				console.error('SiteStaffr: Voice preview error for ' + voice, e);
				resetButton();
				if (window.SiteStaffrModal) {
					window.SiteStaffrModal.alertDialog({ message: 'Could not load voice preview. Please try again.' });
				}
			});

			// Start loading
			audio.load();

			function resetButton() {
				isLoading = false;
				button.removeClass('playing');
				button.find('.dashicons').removeClass('dashicons-controls-pause dashicons-update spin').addClass('dashicons-controls-play');
				currentAudio = null;
			}
		});
	}

})(jQuery);
