/**
 * Basic Forms - AI Form Builder chat widget
 *
 * @package BasicForms
 */
(function ($) {
	'use strict';

	var STORAGE_TRANSFER = 'wppsBfAiChatTransfer';

	$(function () {
		if (typeof wppsBfAiData === 'undefined') {
			return;
		}

		var $chat = $('#wpps-bf-ai-chat');
		if (!$chat.length) {
			return;
		}

		var $panel = $('#wpps-bf-ai-chat-panel');
		var $launcher = $('#wpps-bf-ai-chat-launcher');
		var $messages = $('#wpps-bf-ai-chat-messages');
		var $prompt = $('#wpps-bf-ai-prompt');
		var $send = $('#wpps-bf-ai-send');
		var $loader = $send.find('.wpps-bf-ai-send__loader');
		var $sendLabel = $send.find('.wpps-bf-ai-send__label');
		var strings = wppsBfAiData.strings || {};
		var isBusy = false;
		var isOpen = false;
		var isEditMode = wppsBfAiData.mode === 'edit';
		var messages = [];
		var lastUserPrompt = '';
		var shouldOpenOnLoad = false;

		function storageKey() {
			var formId = parseInt($('input[name="wpps_bf_form_id"]').val(), 10) || 0;
			return 'wppsBfAiChat_' + (wppsBfAiData.mode || 'create') + '_' + formId;
		}

		function escapeHtml(text) {
			return String(text || '')
				.replace(/&/g, '&amp;')
				.replace(/</g, '&lt;')
				.replace(/>/g, '&gt;')
				.replace(/"/g, '&quot;');
		}

		function welcomeMessage() {
			return isEditMode ? (strings.welcomeEdit || '') : (strings.welcomeCreate || '');
		}

		function defaultMessages() {
			var welcome = welcomeMessage();
			if (!welcome) {
				return [];
			}
			return [{ role: 'assistant', content: welcome }];
		}

		function loadMessages() {
			var transferred = sessionStorage.getItem(STORAGE_TRANSFER);
			if (transferred) {
				try {
					var parsedTransfer = JSON.parse(transferred);
					if (Array.isArray(parsedTransfer) && parsedTransfer.length) {
						sessionStorage.removeItem(STORAGE_TRANSFER);
						messages = parsedTransfer;
						shouldOpenOnLoad = true;
						saveMessages();
						return;
					}
				} catch (e) {
					sessionStorage.removeItem(STORAGE_TRANSFER);
				}
			}

			try {
				var stored = sessionStorage.getItem(storageKey());
				if (stored) {
					var parsed = JSON.parse(stored);
					if (Array.isArray(parsed) && parsed.length) {
						messages = parsed;
						return;
					}
				}
			} catch (err) {
				sessionStorage.removeItem(storageKey());
			}

			messages = defaultMessages();
		}

		function saveMessages() {
			try {
				sessionStorage.setItem(storageKey(), JSON.stringify(messages));
			} catch (err) {
				// Ignore quota errors.
			}
		}

		function historyForRequest() {
			var conversational = messages.filter(function (message) {
				return !message.error;
			});

			if (conversational.length <= 1) {
				return [];
			}

			var history = conversational.slice(0, -1).map(function (message) {
				return {
					role: message.role,
					content: message.content
				};
			});

			while (history.length && history[0].role === 'assistant') {
				history.shift();
			}

			return history;
		}

		function renderMessages() {
			var html = '';
			messages.forEach(function (message, index) {
				var roleClass = message.role === 'user' ? 'is-user' : 'is-assistant';
				if (message.error) {
					roleClass += ' is-error';
				} else if (message.notice) {
					roleClass += ' is-notice';
				}
				var roleLabel = message.role === 'user'
					? (strings.you || 'You')
					: (strings.assistant || 'Assistant');
				html += '<div class="wpps-bf-ai-chat-message ' + roleClass + '">';
				html += '<div class="wpps-bf-ai-chat-message__label">' + escapeHtml(roleLabel) + '</div>';
				html += '<div class="wpps-bf-ai-chat-message__bubble">' + escapeHtml(message.content).replace(/\n/g, '<br>') + '</div>';
				if (message.error && index === messages.length - 1 && lastUserPrompt) {
					html += '<button type="button" class="button button-small wpps-bf-ai-chat-retry" data-prompt="' + escapeHtml(lastUserPrompt) + '">' + escapeHtml(strings.retry || 'Retry') + '</button>';
				}
				html += '</div>';
			});

			if (isBusy) {
				html += '<div class="wpps-bf-ai-chat-message is-assistant is-typing">';
				html += '<div class="wpps-bf-ai-chat-message__label">' + escapeHtml(strings.assistant || 'Assistant') + '</div>';
				html += '<div class="wpps-bf-ai-chat-message__bubble"><span class="wpps-bf-ai-chat-typing">' + escapeHtml(strings.thinking || 'Thinking…') + '</span></div>';
				html += '</div>';
			}

			$messages.html(html);
			scrollMessagesToBottom();
		}

		function addMessage(role, content, isError, isNotice) {
			content = (content || '').trim();
			if (!content) {
				return;
			}
			messages.push({
				role: role,
				content: content,
				error: !!isError,
				notice: !!isNotice
			});
			saveMessages();
			renderMessages();
		}

		function removeLastMessage() {
			if (!messages.length) {
				return;
			}
			messages.pop();
			saveMessages();
			renderMessages();
		}

		function scrollMessagesToBottom() {
			if ($messages.length && $messages[0]) {
				$messages.scrollTop($messages[0].scrollHeight);
			}
		}

		function openChat() {
			isOpen = true;
			$chat.addClass('is-open').attr('aria-hidden', 'false');
			$panel.prop('hidden', false);
			$launcher.attr('aria-expanded', 'true');
			// The panel was hidden while messages rendered, so scroll height was 0.
			// Jump to the latest message now that it is visible.
			scrollMessagesToBottom();
			if ($prompt.length && !$prompt.prop('disabled')) {
				$prompt.trigger('focus');
			}
		}

		function closeChat() {
			if (isBusy) {
				return;
			}
			isOpen = false;
			$chat.removeClass('is-open').attr('aria-hidden', 'true');
			$panel.prop('hidden', true);
			$launcher.attr('aria-expanded', 'false');
		}

		function toggleChat() {
			if (isOpen) {
				closeChat();
			} else {
				openChat();
			}
		}

		function setBusy(busy) {
			isBusy = busy;
			$send.prop('disabled', busy || !wppsBfAiData.hasApiKey);
			$prompt.prop('disabled', busy || !wppsBfAiData.hasApiKey);
			$loader.prop('hidden', !busy);
			$sendLabel.prop('hidden', busy);
			$chat.find('.wpps-bf-ai-example, .wpps-bf-ai-chat-clear, .wpps-bf-ai-chat-close').prop('disabled', busy);
			renderMessages();
		}

		function updatePromptCount() {
			var $count = $('#wpps-bf-ai-prompt-count');
			if ($count.length) {
				$count.text(($prompt.val() || '').length);
			}
		}

		function applySettings(settings) {
			if (!settings || typeof settings !== 'object') {
				return;
			}
			if (settings.subject) {
				$('#wpps-bf-subject').val(settings.subject);
			}
			if (settings.success_message) {
				$('#wpps-bf-success-message').val(settings.success_message);
			}
			if (settings.submit_button_text) {
				$('#wpps-bf-submit-text').val(settings.submit_button_text);
			}
			if (settings.redirect_url) {
				$('#wpps-bf-redirect').val(settings.redirect_url);
			}
			if (Object.prototype.hasOwnProperty.call(settings, 'enable_autoreply')) {
				var enabled = settings.enable_autoreply === '1' || settings.enable_autoreply === true || settings.enable_autoreply === 1;
				$('#wpps-bf-enable-autoreply').prop('checked', enabled);
				$('#wpps-bf-autoreply-settings').toggle(enabled);
			}
			if (settings.autoreply_subject) {
				$('#wpps-bf-autoreply-subject').val(settings.autoreply_subject);
			}
			if (settings.autoreply_message) {
				$('#wpps-bf-autoreply-message').val(settings.autoreply_message);
			}
		}

		function getFormContext() {
			if (typeof window.wppsBfGetFormSnapshot === 'function') {
				return window.wppsBfGetFormSnapshot();
			}
			return {
				title: $('#wpps-bf-form-title').val() || '',
				fields: [],
				settings: {}
			};
		}

		function applyDesign(design) {
			if (!design || typeof design !== 'object') {
				return $.Deferred().resolve().promise();
			}
			if (typeof window.wppsBfSyncDesignModalFromSaved === 'function') {
				window.wppsBfSyncDesignModalFromSaved(design);
			}
			var formId = parseInt($('input[name="wpps_bf_form_id"]').val(), 10) || 0;
			if (formId <= 0 || typeof window.wppsBfSaveDesignFromModal !== 'function') {
				return $.Deferred().resolve().promise();
			}
			return window.wppsBfSaveDesignFromModal();
		}

		function handleSuccess(response) {
			var data = response.data || {};
			var assistantMessage = data.assistant_message || strings.applied || 'Done.';
			var nothingChanged = isEditMode && Array.isArray(data.changed) && data.changed.length === 0;

			addMessage('assistant', assistantMessage, false, nothingChanged);

			if (isEditMode) {
				var intent = data.intent || 'modify';
				var changed = Array.isArray(data.changed) ? data.changed : null;

				function didChange(part) {
					// When the backend reports changes, trust it; otherwise fall back to intent rules.
					if (changed) {
						return changed.indexOf(part) !== -1;
					}
					return intent !== 'add_fields' && intent !== 'design';
				}

				if (data.title && didChange('title')) {
					$('#wpps-bf-form-title').val(data.title);
				}
				if (didChange('settings')) {
					applySettings(data.settings);
				}
				if (didChange('fields') && typeof window.wppsBfApplyAiPayload === 'function') {
					window.wppsBfApplyAiPayload(data, intent === 'add_fields' ? 'add_fields' : 'modify');
				}
				applyDesign(data.design);
				return;
			}

			if (data.redirect_url) {
				try {
					sessionStorage.setItem(STORAGE_TRANSFER, JSON.stringify(messages));
					// The new form's conversation moves to the editor, so the "create"
					// chat must reset — otherwise the next new form reuses this thread.
					sessionStorage.removeItem(storageKey());
				} catch (err) {
					// Ignore quota errors.
				}
				window.location.href = data.redirect_url;
			}
		}

		function sendMessage(text, options) {
			options = options || {};
			text = (text || '').trim();
			if (!text || isBusy || !wppsBfAiData.hasApiKey) {
				return;
			}

			if (!options.skipUserMessage) {
				addMessage('user', text, false);
				$prompt.val('');
				updatePromptCount();
			}

			lastUserPrompt = text;

			var postData = {
				action: 'wpps_basic_forms_ai_generate',
				nonce: wppsBfAiData.nonce,
				prompt: text,
				mode: wppsBfAiData.mode || 'create',
				history: JSON.stringify(historyForRequest())
			};

			if (isEditMode) {
				postData.form_context = JSON.stringify(getFormContext());
			}

			setBusy(true);

			$.post(wppsBfAiData.ajaxUrl, postData).done(function (response) {
				if (!response || !response.success) {
					var msg = response && response.data && response.data.message
						? response.data.message
						: strings.networkError;
					if (response && response.data && response.data.code === 'rate_limit') {
						msg = strings.rateLimited || msg;
					}
					addMessage('assistant', msg, true);
					return;
				}
				handleSuccess(response);
			}).fail(function () {
				addMessage('assistant', strings.networkError || 'Network error. Please try again.', true);
			}).always(function () {
				setBusy(false);
			});
		}

		function clearChat() {
			if (isBusy) {
				return;
			}
			if (!window.confirm(strings.clearConfirm || 'Clear this conversation?')) {
				return;
			}
			messages = defaultMessages();
			lastUserPrompt = '';
			saveMessages();
			renderMessages();
		}

		loadMessages();
		renderMessages();
		updatePromptCount();

		if (shouldOpenOnLoad) {
			openChat();
		}

		$(document).on('click', '#wpps-bf-open-ai-builder, #wpps-bf-open-ai-builder-hero, #wpps-bf-open-ai-builder-promo, .wpps-bf-open-ai-builder', function (e) {
			e.preventDefault();
			openChat();
		});

		$launcher.on('click', function (e) {
			e.preventDefault();
			toggleChat();
		});

		$('#wpps-bf-ai-chat-close').on('click', function (e) {
			e.preventDefault();
			closeChat();
		});

		$('#wpps-bf-ai-chat-clear').on('click', function (e) {
			e.preventDefault();
			clearChat();
		});

		$(document).on('click', '.wpps-bf-ai-chat-retry', function () {
			var text = $(this).data('prompt') || lastUserPrompt;
			if (!text || isBusy) {
				return;
			}
			removeLastMessage();
			sendMessage(text, { skipUserMessage: true });
		});

		$prompt.on('input', updatePromptCount);

		$prompt.on('keydown', function (e) {
			if (e.key === 'Enter' && !e.shiftKey) {
				e.preventDefault();
				sendMessage($prompt.val());
			}
		});

		$send.on('click', function () {
			sendMessage($prompt.val());
		});
	});
})(jQuery);
