/* global CsWidgetsAdminL10n */
( function () {
	'use strict';

	var l10n = window.CsWidgetsAdminL10n || {};

	function buildShortcode( tag, attrs ) {
		var parts = [];
		Object.keys( attrs ).forEach( function ( k ) {
			var v = String( attrs[ k ] );
			if ( v.indexOf( '"' ) !== -1 ) {
				parts.push( k + "='" + v.replace( /\\/g, '\\\\' ).replace( /'/g, "\\'" ) + "'" );
			} else {
				parts.push( k + '="' + v.replace( /\\/g, '\\\\' ) + '"' );
			}
		} );
		return '[' + tag + ( parts.length ? ' ' + parts.join( ' ' ) : '' ) + ']';
	}

	function getFormValue( name ) {
		var el = document.querySelector( '[name="' + name + '"]' );
		if ( ! el ) return '';
		return el.type === 'checkbox' ? ( el.checked ? '1' : '0' ) : ( el.value || '' ).trim();
	}

	function buildChatShortcodeFromForm() {
		var map = {
			'cswidgets_options[chat_title]': 'title',
			'cswidgets_options[chat_subtitle]': 'subtitle',
			'cswidgets_options[chat_position]': 'position',
			'cswidgets_options[chat_primary_color]': 'primary_color',
			'cswidgets_options[chat_hover_color]': 'hover_color',
			'cswidgets_options[chat_show_avatar]': 'show_avatar',
			'cswidgets_options[chat_enable_sound]': 'enable_sound',
			'cswidgets_options[chat_welcome_message]': 'welcome_message',
			'cswidgets_options[chat_placeholder]': 'placeholder',
			'cswidgets_options[chat_variants]': 'variants',
			'cswidgets_options[chat_variant_filters]': 'variant_filters',
			'cswidgets_options[chat_dynamic_params]': 'dynamic_params',
		};
		var attrs = {};
		Object.keys( map ).forEach( function ( name ) {
			var val = getFormValue( name );
			if ( val !== '' ) attrs[ map[ name ] ] = val;
		} );
		return buildShortcode( 'cswidgets_chat', attrs );
	}

	function buildSearchShortcodeFromForm() {
		var map = {
			'cswidgets_options[search_position]': 'position',
			'cswidgets_options[search_primary_color]': 'primary_color',
			'cswidgets_options[search_hover_color]': 'hover_color',
			'cswidgets_options[search_placeholder]': 'placeholder',
			'cswidgets_options[search_limit]': 'limit',
			'cswidgets_options[product_variants]': 'variants',
			'cswidgets_options[product_variant_filters]': 'variant_filters',
			'cswidgets_options[product_dynamic_params]': 'dynamic_params',
			'cswidgets_options[search_show_catalog_button]': 'show_catalog_button',
			'cswidgets_options[search_catalog_button_label]': 'catalog_button_label',
			'cswidgets_options[ask_enabled]': 'show_ask_ai_button',
			'cswidgets_options[ask_button_label]': 'ask_ai_button_label',
			'cswidgets_options[ask_placeholder]': 'ask_ai_placeholder',
		};
		var attrs = {};
		Object.keys( map ).forEach( function ( name ) {
			var val = getFormValue( name );
			if ( val !== '' ) attrs[ map[ name ] ] = val;
		} );
		return buildShortcode( 'cswidgets_search', attrs );
	}

	function buildAskShortcodeFromForm() {
		var map = {
			'cswidgets_options[ask_position]': 'position',
			'cswidgets_options[ask_primary_color]': 'primary_color',
			'cswidgets_options[ask_button_label]': 'button_label',
			'cswidgets_options[ask_placeholder]': 'placeholder',
			'cswidgets_options[product_variants]': 'variants',
			'cswidgets_options[product_variant_filters]': 'variant_filters',
			'cswidgets_options[product_dynamic_params]': 'dynamic_params',
		};
		var attrs = {};
		Object.keys( map ).forEach( function ( name ) {
			var val = getFormValue( name );
			if ( val !== '' ) attrs[ map[ name ] ] = val;
		} );
		return buildShortcode( 'cswidgets_ask', attrs );
	}

	function fallbackCopy( text, button, originalLabel ) {
		var ta = document.createElement( 'textarea' );
		ta.value = text;
		ta.style.position = 'fixed';
		ta.style.left = '-9999px';
		document.body.appendChild( ta );
		ta.select();
		var ok = false;
		try {
			ok = document.execCommand( 'copy' );
		} catch ( e ) {}
		button.textContent = ok ? ( l10n.copied || 'Copied!' ) : ( l10n.failed || 'Failed!' );
		setTimeout( function () { button.textContent = originalLabel; }, 2000 );
		document.body.removeChild( ta );
	}

	function copyToClipboard( text, button ) {
		var originalLabel = button.textContent;
		if ( navigator.clipboard && navigator.clipboard.writeText ) {
			navigator.clipboard.writeText( text ).then( function () {
				button.textContent = l10n.copied || 'Copied!';
				setTimeout( function () { button.textContent = originalLabel; }, 2000 );
			} ).catch( function () {
				fallbackCopy( text, button, originalLabel );
			} );
		} else {
			fallbackCopy( text, button, originalLabel );
		}
	}

	function convertToJson( fieldName ) {
		var simpleInput = document.getElementById( fieldName + '_simple' );
		var jsonInput = document.getElementById( fieldName );
		if ( ! simpleInput || ! jsonInput ) return;

		var simpleValue = simpleInput.value.trim();
		if ( ! simpleValue ) {
			window.alert( l10n.conversion_required || 'Please enter parameters in simple format first.' );
			return;
		}

		var json = {};
		simpleValue.split( ',' ).forEach( function ( pair ) {
			var trimmed = pair.trim();
			var eqIdx = trimmed.indexOf( '=' );
			if ( eqIdx === -1 ) return;
			var key = trimmed.substring( 0, eqIdx ).trim();
			if ( ! key ) return;
			var value = trimmed.substring( eqIdx + 1 ).trim();

			var source = 'localStorage';
			var storageKey = key;

			var atIdx = key.indexOf( '@' );
			if ( atIdx !== -1 ) {
				storageKey = key.substring( 0, atIdx ).trim();
				var sourceType = key.substring( atIdx + 1 ).trim().toLowerCase();
				if ( sourceType === 'cookie' || sourceType === 'cookies' ) {
					source = 'cookie';
				} else if ( sourceType === 'session' || sourceType === 'sessionstorage' ) {
					source = 'sessionStorage';
				}
			}

			json[ storageKey ] = { source: source, name: value || storageKey };
		} );

		if ( Object.keys( json ).length > 0 ) {
			jsonInput.value = JSON.stringify( json, null, 2 );
			window.alert( l10n.converted_to_json || 'Converted to JSON format! You can now customize the storage sources if needed.' );
		} else {
			window.alert( l10n.no_valid_pairs || 'No valid key=value pairs found. Please use format: key=value,key2=value2' );
		}
	}

	window.cswidgetsConvertToJson = convertToJson;

	document.addEventListener( 'DOMContentLoaded', function () {
		var settingsForm = document.getElementById( 'cswidgets-settings-form' );
		var tabs = Array.prototype.slice.call( document.querySelectorAll( '[data-cswidgets-tab]' ) );
		var panels = Array.prototype.slice.call( document.querySelectorAll( '[data-cswidgets-panel]' ) );
		var previewScenes = Array.prototype.slice.call( document.querySelectorAll( '[data-cswidgets-preview]' ) );

		function findField( name ) {
			return document.querySelector( '[name="cswidgets_options[' + name + ']"]' );
		}

		function fieldValue( name, fallback ) {
			var field = findField( name );
			if ( ! field ) return fallback || '';
			if ( field.type === 'checkbox' ) return field.checked;
			return field.value || fallback || '';
		}

		function setText( id, value ) {
			var target = document.getElementById( id );
			if ( target ) target.textContent = value;
		}

		function setColour( selector, value ) {
			document.querySelectorAll( selector ).forEach( function ( target ) {
				target.style.backgroundColor = value;
			} );
		}

		function setActiveTab( name, focusTab ) {
			var activeTab = null;
			tabs.forEach( function ( tab ) {
				var isActive = tab.getAttribute( 'data-cswidgets-tab' ) === name;
				tab.setAttribute( 'aria-selected', isActive ? 'true' : 'false' );
				tab.setAttribute( 'tabindex', isActive ? '0' : '-1' );
				if ( isActive ) activeTab = tab;
			} );
			panels.forEach( function ( panel ) {
				panel.hidden = panel.getAttribute( 'data-cswidgets-panel' ) !== name;
			} );
			previewScenes.forEach( function ( scene ) {
				scene.hidden = scene.getAttribute( 'data-cswidgets-preview' ) !== name;
			} );
			if ( focusTab && activeTab ) activeTab.focus();
		}

		tabs.forEach( function ( tab, index ) {
			tab.addEventListener( 'click', function () {
				setActiveTab( tab.getAttribute( 'data-cswidgets-tab' ), false );
			} );
			tab.addEventListener( 'keydown', function ( event ) {
				if ( event.key !== 'ArrowLeft' && event.key !== 'ArrowRight' && event.key !== 'Home' && event.key !== 'End' ) return;
				event.preventDefault();
				var nextIndex = index;
				if ( event.key === 'ArrowRight' ) nextIndex = ( index + 1 ) % tabs.length;
				if ( event.key === 'ArrowLeft' ) nextIndex = ( index - 1 + tabs.length ) % tabs.length;
				if ( event.key === 'Home' ) nextIndex = 0;
				if ( event.key === 'End' ) nextIndex = tabs.length - 1;
				setActiveTab( tabs[ nextIndex ].getAttribute( 'data-cswidgets-tab' ), true );
			} );
		} );

		function toggleDependentRow( controlName, rowClass, expectedValue ) {
			var control = findField( controlName );
			var row = document.querySelector( rowClass );
			if ( ! control || ! row ) return;
			var shouldShow = control.type === 'checkbox' ? control.checked : control.value === expectedValue;
			row.hidden = ! shouldShow;
		}

		function updatePreview() {
			var chatColour = fieldValue( 'chat_primary_color', '#173f35' );
			var searchColour = fieldValue( 'search_primary_color', '#2563eb' );
			var askColour = fieldValue( 'ask_primary_color', '#3b82f6' );
			var chatCard = document.getElementById( 'cswidgets-chat-preview-card' );
			var avatar = document.getElementById( 'cswidgets-preview-avatar' );
			var catalogButton = document.getElementById( 'cswidgets-preview-catalog-button' );

			setText( 'cswidgets-preview-chat-title', fieldValue( 'chat_title', 'Chat with us!' ) );
			setText( 'cswidgets-preview-chat-subtitle', fieldValue( 'chat_subtitle', 'Ask about our products' ) );
			setText( 'cswidgets-preview-chat-message', fieldValue( 'chat_welcome_message', 'Hi! How can I help you today?' ) );
			setText( 'cswidgets-preview-chat-placeholder', fieldValue( 'chat_placeholder', 'Type your message…' ) );
			setColour( '#cswidgets-preview-chat-head, .cswidgets-widget-input i', chatColour );
			if ( chatCard ) {
				chatCard.setAttribute( 'data-position', fieldValue( 'chat_position', 'bottom-right' ) );
				chatCard.classList.toggle( 'is-widget-disabled', ! fieldValue( 'chat_enabled', false ) );
			}
			if ( avatar ) avatar.classList.toggle( 'is-hidden', ! fieldValue( 'chat_show_avatar', false ) );

			setText( 'cswidgets-preview-search-placeholder', fieldValue( 'search_placeholder', 'Search products…' ) );
			setText( 'cswidgets-preview-catalog-button', fieldValue( 'search_catalog_button_label', 'Browse catalog' ) );
			if ( catalogButton ) {
				catalogButton.style.backgroundColor = searchColour;
				catalogButton.hidden = ! fieldValue( 'search_show_catalog_button', false );
				catalogButton.closest( '.cswidgets-search-preview-window' ).classList.toggle( 'is-widget-disabled', ! fieldValue( 'search_enabled', false ) );
			}

			setText( 'cswidgets-preview-ask-label', fieldValue( 'ask_button_label', 'Ask AI' ) );
			setText( 'cswidgets-preview-ask-placeholder', fieldValue( 'ask_placeholder', 'Ask a question…' ) );
			setColour( '.cswidgets-ask-preview-window > div i', askColour );
			var askWindow = document.querySelector( '.cswidgets-ask-preview-window' );
			var askIcon = document.querySelector( '.cswidgets-ask-preview-window > .dashicons' );
			if ( askWindow ) askWindow.classList.toggle( 'is-widget-disabled', ! fieldValue( 'ask_enabled', false ) );
			if ( askIcon ) askIcon.style.color = askColour;

			var locale = String( fieldValue( 'widget_locale', 'auto' ) ).toUpperCase();
			setText( 'cswidgets-preview-locale', locale );
			setText( 'cswidgets-preview-sync', fieldValue( 'realtime_sync_enabled', false ) ? ( l10n.on || 'On' ) : ( l10n.off || 'Off' ) );
			setText( 'cswidgets-preview-variants', fieldValue( 'product_variants', 'none' ) );
			setText( 'cswidgets-preview-filters', fieldValue( 'product_variant_filters', '' ) ? ( l10n.configured || 'Configured' ) : ( l10n.none || 'None' ) );

			toggleDependentRow( 'search_show_catalog_button', '.cswidgets-field-search_catalog_button_label' );
			toggleDependentRow( 'search_mount_mode', '.cswidgets-field-search_container_selector', 'inline' );
			toggleDependentRow( 'search_mount_mode', '.cswidgets-field-search_full_width', 'inline' );
			toggleDependentRow( 'ask_mount_mode', '.cswidgets-field-ask_container_selector', 'inline' );
		}

		if ( settingsForm ) {
			settingsForm.addEventListener( 'input', updatePreview );
			settingsForm.addEventListener( 'change', updatePreview );
			var markDirty = function () {
				var saveMessage = document.querySelector( '.cswidgets-save-bar > span' );
				if ( ! saveMessage ) return;
				saveMessage.classList.add( 'is-dirty' );

				// The label is an icon element followed by a bare text node.
				// Writing to lastChild blindly would silently do nothing if that
				// markup ever changes — nodeValue is not settable on an element —
				// so replace the trailing text node only when there is one.
				var message = l10n.unsaved || 'You have unsaved changes.';
				var last = saveMessage.lastChild;
				if ( last && last.nodeType === Node.TEXT_NODE ) {
					last.nodeValue = message;
				} else {
					saveMessage.appendChild( document.createTextNode( message ) );
				}
			};
			settingsForm.addEventListener( 'input', markDirty );
			settingsForm.addEventListener( 'change', markDirty );
		}

		var chatBtn = document.getElementById( 'cswidgets-copy-chat-shortcode' );
		if ( chatBtn ) {
			chatBtn.addEventListener( 'click', function () {
				var el = document.getElementById( 'cswidgets-chat-shortcode-text' );
				if ( el ) copyToClipboard( el.getAttribute( 'data-shortcode' ) || el.textContent, chatBtn );
			} );
		}

		var searchBtn = document.getElementById( 'cswidgets-copy-search-shortcode' );
		if ( searchBtn ) {
			searchBtn.addEventListener( 'click', function () {
				var el = document.getElementById( 'cswidgets-search-shortcode-text' );
				if ( el ) copyToClipboard( el.getAttribute( 'data-shortcode' ) || el.textContent, searchBtn );
			} );
		}

		var askBtn = document.getElementById( 'cswidgets-copy-ask-shortcode' );
		if ( askBtn ) {
			askBtn.addEventListener( 'click', function () {
				var el = document.getElementById( 'cswidgets-ask-shortcode-text' );
				if ( el ) copyToClipboard( el.getAttribute( 'data-shortcode' ) || el.textContent, askBtn );
			} );
		}

		function updateChatShortcodeDisplay() {
			var el = document.getElementById( 'cswidgets-chat-shortcode-text' );
			if ( ! el ) return;
			var code = buildChatShortcodeFromForm();
			el.textContent = code;
			el.setAttribute( 'data-shortcode', code );
		}

		function updateSearchShortcodeDisplay() {
			var el = document.getElementById( 'cswidgets-search-shortcode-text' );
			if ( ! el ) return;
			var code = buildSearchShortcodeFromForm();
			el.textContent = code;
			el.setAttribute( 'data-shortcode', code );
		}

		function updateAskShortcodeDisplay() {
			var el = document.getElementById( 'cswidgets-ask-shortcode-text' );
			if ( ! el ) return;
			var code = buildAskShortcodeFromForm();
			el.textContent = code;
			el.setAttribute( 'data-shortcode', code );
		}

		document.querySelectorAll(
			'select[name^="cswidgets_options[chat_"], input[name^="cswidgets_options[chat_"], textarea[name="cswidgets_options[chat_dynamic_params]"]'
		).forEach( function ( el ) {
			el.addEventListener( 'change', updateChatShortcodeDisplay );
			el.addEventListener( 'input', updateChatShortcodeDisplay );
		} );

		document.querySelectorAll(
			'select[name^="cswidgets_options[search_"], input[name^="cswidgets_options[search_"], textarea[name="cswidgets_options[search_dynamic_params]"]'
		).forEach( function ( el ) {
			el.addEventListener( 'change', updateSearchShortcodeDisplay );
			el.addEventListener( 'input', updateSearchShortcodeDisplay );
		} );

		document.querySelectorAll(
			'select[name^="cswidgets_options[ask_"], input[name^="cswidgets_options[ask_"], textarea[name="cswidgets_options[ask_dynamic_params]"]'
		).forEach( function ( el ) {
			el.addEventListener( 'change', updateAskShortcodeDisplay );
			el.addEventListener( 'input', updateAskShortcodeDisplay );
		} );

		document.querySelectorAll(
			'input[name="cswidgets_options[ask_enabled]"], input[name="cswidgets_options[ask_button_label]"], input[name="cswidgets_options[ask_placeholder]"]'
		).forEach( function ( el ) {
			el.addEventListener( 'change', updateSearchShortcodeDisplay );
			el.addEventListener( 'input', updateSearchShortcodeDisplay );
		} );

		document.querySelectorAll(
			'select[name^="cswidgets_options[product_"], input[name^="cswidgets_options[product_"], textarea[name="cswidgets_options[product_dynamic_params]"]'
		).forEach( function ( el ) {
			el.addEventListener( 'change', updateSearchShortcodeDisplay );
			el.addEventListener( 'input', updateSearchShortcodeDisplay );
			el.addEventListener( 'change', updateAskShortcodeDisplay );
			el.addEventListener( 'input', updateAskShortcodeDisplay );
		} );

		updateChatShortcodeDisplay();
		updateSearchShortcodeDisplay();
		updateAskShortcodeDisplay();
		updatePreview();
		initSyncProgress();
	} );

	/**
	 * Poll the sync progress bar.
	 *
	 * Talks to admin-ajax.php, never to ChatSell directly — the webhook secret
	 * that signs the real request stays in PHP.
	 */
	function initSyncProgress() {
		var panel = document.querySelector( '.cswidgets-sync-progress' );
		if ( ! panel || ! window.CsWidgetsAdminL10n || ! CsWidgetsAdminL10n.ajaxUrl ) {
			return;
		}
		if ( ! panel.getAttribute( 'data-task' ) ) {
			return;
		}

		var bar = panel.querySelector( '.cswidgets-progress-bar' );
		var label = panel.querySelector( '.cswidgets-progress-label' );
		if ( ! bar || ! label ) {
			return;
		}

		var delay = 2000;
		var timer = null;
		var pollCount = 0;
		var consecutiveErrors = 0;
		var maxPolls = 240;
		var maxConsecutiveErrors = 3;

		panel.hidden = false;
		label.textContent = CsWidgetsAdminL10n.syncQueued || 'Waiting for a worker to pick this up…';

		// Announced rather than merely drawn: a bar that only moves visually
		// leaves a screen-reader user with no idea a sync is progressing.
		bar.setAttribute( 'role', 'progressbar' );
		bar.setAttribute( 'aria-valuemin', '0' );
		bar.setAttribute( 'aria-valuemax', '100' );
		bar.setAttribute( 'aria-valuenow', '0' );
		label.setAttribute( 'role', 'status' );
		label.setAttribute( 'aria-live', 'polite' );

		function setProgress( value ) {
			var clamped = Math.max( 0, Math.min( 100, value ) );
			bar.style.width = clamped + '%';
			bar.setAttribute( 'aria-valuenow', String( Math.round( clamped ) ) );
		}

		function stop( text, failed ) {
			if ( timer ) {
				clearTimeout( timer );
				timer = null;
			}
			label.textContent = text;
			panel.classList.toggle( 'is-failed', !! failed );
		}

		function poll() {
			pollCount += 1;
			if ( pollCount > maxPolls ) {
				stop( CsWidgetsAdminL10n.syncTakingLonger, false );
				return;
			}

			var body = new URLSearchParams();
			body.append( 'action', 'cswidgets_sync_status' );
			body.append( '_wpnonce', CsWidgetsAdminL10n.syncStatusNonce );

			fetch( CsWidgetsAdminL10n.ajaxUrl, {
				method: 'POST',
				credentials: 'same-origin',
				headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
				body: body.toString()
			} )
				.then( function ( response ) {
					if ( ! response.ok ) {
						throw new Error( 'HTTP ' + response.status );
					}
					return response.json();
				} )
				.then( function ( payload ) {
					if ( ! payload || ! payload.success || ! payload.data ) {
						throw new Error( 'Invalid sync status response' );
					}

					var data = payload.data;
					var supportedStatuses = [ 'queued', 'running', 'completed', 'failed' ];
					if ( -1 === supportedStatuses.indexOf( data.sync_status ) ) {
						stop( CsWidgetsAdminL10n.syncUnavailable, false );
						return;
					}
					consecutiveErrors = 0;
					var progress = typeof data.sync_progress === 'number' ? data.sync_progress : null;
					if ( null !== progress ) {
						setProgress( progress );
					}

					if ( 'completed' === data.sync_status ) {
						setProgress( 100 );
						stop( data.sync_message || CsWidgetsAdminL10n.syncCompleted, false );
						return;
					}
					if ( 'failed' === data.sync_status ) {
						stop( data.sync_error || data.sync_message || CsWidgetsAdminL10n.syncFailed, true );
						return;
					}

					label.textContent = data.sync_message ||
						( 'running' === data.sync_status ? CsWidgetsAdminL10n.syncRunning : CsWidgetsAdminL10n.syncQueued );

					// Ease off gradually: a large catalogue can sync for a long
					// time, and a 2s poll for an hour is pure noise.
					delay = Math.min( 15000, Math.round( delay * 1.2 ) );
					timer = setTimeout( poll, delay );
				} )
				.catch( function () {
					consecutiveErrors += 1;
					if ( consecutiveErrors >= maxConsecutiveErrors ) {
						stop( CsWidgetsAdminL10n.syncUnavailable, false );
						return;
					}
					delay = Math.min( 15000, Math.round( delay * 1.5 ) );
					timer = setTimeout( poll, delay );
				} );
		}

		timer = setTimeout( poll, 800 );
	}
} )();
