(function( $ ) {
	'use strict';

	/**
	 * All of the code for your admin-facing JavaScript source
	 * should reside in this file.
	 *
	 * Note: It has been assumed you will write jQuery code here, so the
	 * $ function reference has been prepared for usage within the scope
	 * of this function.
	 *
	 * This enables you to define handlers, for when the DOM is ready:
	 *
	 * $(function() {
	 *
	 * });
	 *
	 * When the window is loaded:
	 *
	 * $( window ).load(function() {
	 *
	 * });
	 *
	 * ...and/or other possibilities.
	 *
	 * Ideally, it is not considered best practise to attach more than a
	 * single DOM-ready or window-load handler for a particular page.
	 * Although scripts in the WordPress core, Plugins and Themes may be
	 * practising this, we should strive to set a better example in our own work.
	 */

	//jQuery('#ffl_list_background_option').iris();
	//jQuery('#ffl_list_text_option').iris();
	// Restore tab/sub-tab from URL hash only; otherwise click default.
	$(document).ready(function(){
		try {
			// When no API key is set, the PHP hides the tab nav; do not override that.
			if (typeof window.gffcIsTabNavHidden === 'function' && window.gffcIsTabNavHidden()) {
				return;
			}

			if (typeof window.gffcRestoreDeepLinkState === 'function') {
				if (window.gffcRestoreDeepLinkState()) {
					return;
				}
			}

			if (document.getElementById("defaultOpen") != null){
				document.getElementById("defaultOpen").click();
			}
		} catch (e) {
			// Fallback: keep existing behavior.
			if (document.getElementById("defaultOpen") != null){
				document.getElementById("defaultOpen").click();
			}
		}
	});

})( jQuery );


function gffcIsTabNavHidden() {
	var tabBar = document.getElementById('cockpit_main_tab_control');
	if (!tabBar) return false;
	// offsetParent is null when display:none (or detached)
	if (tabBar.offsetParent === null) return true;
	try {
		var cs = window.getComputedStyle(tabBar);
		return !!(cs && cs.display === 'none');
	} catch (e) {
		return false;
	}
}

function gffcGetRequestedTabName() {
	var p = gffcParseDeepLink();
	return p && p.tab ? p.tab : '';
}

function gffcGetRequestedConfigSubTabId() {
	var p = gffcParseDeepLink();
	if (!p || p.tab !== 'configuration') return '';
	return p.sub || '';
}

function gffcParseDeepLink() {
	var raw = (window.location && window.location.hash) ? String(window.location.hash) : '';
	if (!raw) return { tab: '', sub: '' };
	raw = raw.replace(/^#/, '').trim();
	if (!raw) return { tab: '', sub: '' };

	var mainPart = raw;
	var queryPart = '';
	var qIdx = raw.indexOf('?');
	if (qIdx !== -1) {
		mainPart = raw.substring(0, qIdx);
		queryPart = raw.substring(qIdx + 1);
	}

	var tab = mainPart;
	var sub = '';
	if (mainPart.indexOf('/') !== -1) {
		var parts = mainPart.split('/');
		tab = parts[0] || '';
		sub = parts[1] || '';
	} else if (mainPart.indexOf(':') !== -1) {
		var parts2 = mainPart.split(':');
		tab = parts2[0] || '';
		sub = parts2[1] || '';
	}

	// Optional query support: #configuration?sub=targets
	if (!sub && queryPart) {
		try {
			var params = new URLSearchParams(queryPart);
			sub = params.get('sub') || params.get('config') || '';
		} catch (e) {
			// Ignore.
		}
	}

	try { tab = decodeURIComponent(tab); } catch (e) {}
	try { sub = decodeURIComponent(sub); } catch (e) {}
	return { tab: String(tab || '').trim(), sub: String(sub || '').trim() };
}

function gffcFindTabButton(tabName) {
	var buttons = document.querySelectorAll('button.tablinks');
	for (var i = 0; i < buttons.length; i++) {
		var btn = buttons[i];
		var oc = btn.getAttribute('onclick') || '';
		if (oc.indexOf("'" + tabName + "'") !== -1 || oc.indexOf('"' + tabName + '"') !== -1) {
			return btn;
		}
	}
	return null;
}

function gffcActivateTab(tabName) {
	if (!tabName) return false;
	if (!document.getElementById(tabName)) return false;
	var btn = gffcFindTabButton(tabName);
	if (!btn) return false;
	btn.click();
	return true;
}

function gffcSetActiveTabDeepLink(tabName) {
	if (!tabName) return;
	try {
		var sub = '';
		if (String(tabName) === 'configuration') {
			// Prefer the currently active configuration sub-tab, otherwise last stored.
			sub = gffcGetActiveConfigSubTabId();
		}

		var base = String(window.location.href || '').split('#')[0];
		var next = base + '#' + encodeURIComponent(String(tabName));
		if (String(tabName) === 'configuration' && sub) {
			next += '/' + encodeURIComponent(String(sub));
		}
		// replaceState avoids scroll-jump.
		if (window.history && typeof window.history.replaceState === 'function') {
			window.history.replaceState(null, '', next);
		} else {
			window.location.hash = String(tabName);
		}
	} catch (e) {}
}

function gffcGetActiveConfigSubTabId() {
	var active = document.querySelector('#configTabs a.nav-link.active');
	if (active) {
		var href = active.getAttribute('href') || '';
		if (href && href.charAt(0) === '#') return href.substring(1);
	}
	var pane = document.querySelector('#configTabContent .tab-pane.active');
	if (pane && pane.id) return pane.id;
	return '';
}

function gffcActivateConfigSubTab(subTabId) {
	if (!subTabId) return false;
	var sel = '#configTabs a.nav-link[href="#' + String(subTabId).replace(/"/g, '') + '"]';
	var a = document.querySelector(sel);
	if (!a) return false;
	if (a.getAttribute('aria-disabled') === 'true') return false;
	// Prefer bootstrap/jQuery tab API when available.
	try {
		if (window.jQuery && typeof window.jQuery === 'function' && typeof window.jQuery(a).tab === 'function') {
			window.jQuery(a).tab('show');
			return true;
		}
	} catch (e) {}
	try { a.click(); } catch (e) { return false; }
	return true;
}

function gffcActivateConfigSubTabWithRetry(subTabId, timeoutMs) {
	var target = String(subTabId || '').trim();
	if (!target) return;
	var timeout = typeof timeoutMs === 'number' ? timeoutMs : 5000;
	var start = Date.now();

	var attempt = function () {
		if (Date.now() - start > timeout) return;
		// Wait until config tabs are in the DOM.
		if (!document.getElementById('configTabs') || !document.getElementById('configTabContent')) {
			setTimeout(attempt, 100);
			return;
		}
		var ok = gffcActivateConfigSubTab(target);
		if (!ok) {
			setTimeout(attempt, 150);
		}
	};

	attempt();
}

function gffcRestoreDeepLinkState() {
	// Returns true if we applied a deep link / restored state.
	if (typeof window.gffcIsTabNavHidden === 'function' && window.gffcIsTabNavHidden()) {
		return false;
	}

	var parsed = gffcParseDeepLink();
	var requestedTab = parsed && parsed.tab ? parsed.tab : '';
	var requestedSub = (requestedTab === 'configuration' && parsed && parsed.sub) ? parsed.sub : '';
	if (!requestedTab) return false;
	var tabToOpen = requestedTab;

	var opened = false;
	if (typeof window.gffcActivateTab === 'function') {
		opened = window.gffcActivateTab(tabToOpen);
	}
	if (!opened) return false;

	// If config tab opened, restore sub-tab after DOM/Bootstrap are ready.
	if (String(tabToOpen) === 'configuration') {
		if (requestedSub) {
			gffcActivateConfigSubTabWithRetry(requestedSub, 6000);
		}
	}

	return true;
}

// Apply deep link when hash changes (manual URL edits/back/forward).
if (!window.gffcHashChangeBound) {
	window.gffcHashChangeBound = true;
	window.addEventListener('hashchange', function () {
		try {
			if (typeof window.gffcRestoreDeepLinkState === 'function') {
				window.gffcRestoreDeepLinkState();
			}
		} catch (e) {}
	});
}

function gffcSetActiveConfigSubTabDeepLink(subTabId) {
	if (!subTabId) return;

	// Only update hash when Configuration is the active main tab.
	var configurationPane = document.getElementById('configuration');
	var isConfigVisible = false;
	try {
		isConfigVisible = !!(configurationPane && window.getComputedStyle(configurationPane).display !== 'none');
	} catch (e) {
		isConfigVisible = false;
	}
	if (isConfigVisible) {
		gffcSetActiveTabDeepLink('configuration');
	}
}


function setConfig(g_ffl_cockpit_key){
	// check if there are no errors
	if (editor.lastSchemaErrors.length==0){
		var config_json = editor.getText();
		document.getElementById('g_ffl_cockpit_configuration').value = config_json; 
		// submit to FFL API
		return fetch("https://ffl-api.garidium.com/", {
			method: "POST",
			headers: {
			"Accept": "application/json",
			"Content-Type": "application/json",
			"x-api-key": window.gFFLCockpit.apiKey,
			},
			body: JSON.stringify({
				"action": "update_subscription", 
				"data": {
					"api_key": g_ffl_cockpit_key, 
					"updates": {"cockpit_configuration": config_json},
					"wp_user": window.gFFLCockpit.currentUser,
					"validate_product_counts": true
				}
			})
		})
		.then((response) => response.json())
		.then((data) => {
			console.log("g-FFL Cockpit Configuration Changes - Full Response:", data);
			// Return the full response data for the modal to handle
			// success=true means save was successful, success=false with no error_message means no changes
			return {
				success: data.success === true,
				error_message: data.error_message || null,
				warning_message: data.warning_message || null,
				no_changes: data.success === false && !data.error_message,
				data: data
			};
		})
		.catch((error) => {
			console.error("API Error:", error);
			return {
				success: false,
				error_message: "Error saving configuration. Please try again.",
				warning_message: null,
				data: null
			};
		});
	}else{
		return Promise.resolve({
			success: false,
			error_message: "Configuration Errors need to be resolved before saving.",
			warning_message: null,
			data: null
		});
	}
}

function openTab(evt, tabName) {
	// Declare all variables
	var i, tabcontent, tablinks;
  
	// Get all elements with class="tabcontent" and hide them
	tabcontent = document.getElementsByClassName("tabcontent");
	for (i = 0; i < tabcontent.length; i++) {
	  tabcontent[i].style.display = "none";
	}
  
	// Get all elements with class="tablinks" and remove the class "active"
	tablinks = document.getElementsByClassName("tablinks");
	for (i = 0; i < tablinks.length; i++) {
	  tablinks[i].className = tablinks[i].className.replace(" active", "");
	}
  
	// Show the current tab, and add an "active" class to the button that opened the tab
	document.getElementById(tabName).style.display = "block";
	evt.currentTarget.className += " active";
	// Deep link: preserve selected tab on refresh.
	if (typeof window.gffcIsTabNavHidden !== 'function' || !window.gffcIsTabNavHidden()) {
		gffcSetActiveTabDeepLink(tabName);
	}

	// Close Help Center panel when leaving the Help Center tab.
	if (String(tabName) !== 'help_center') {
		try { gffcCloseHelpdesk(); } catch (e) {}
	}

	// If the URL explicitly requests a Configuration sub-tab, activate it.
	if (String(tabName) === 'configuration') {
		var requestedSub = '';
		try {
			requestedSub = gffcGetRequestedConfigSubTabId();
		} catch (e) {
			requestedSub = '';
		}
		if (requestedSub) {
			gffcActivateConfigSubTabWithRetry(requestedSub, 6000);
		}
	}
}

function gffcOpenHelpdesk() {
	var overlay = document.getElementById('gffc-helpdesk-overlay');
	if (!overlay) return;
	overlay.classList.add('is-open');
	overlay.setAttribute('aria-hidden', 'false');
	try {
		var input = document.getElementById('ai-question-input');
		if (input) {
			setTimeout(function () { input.focus(); }, 0);
		}
	} catch (e) {}
}

function gffcCloseHelpdesk(evt) {
	if (evt && evt.target && evt.currentTarget && evt.target !== evt.currentTarget) return;
	var overlay = document.getElementById('gffc-helpdesk-overlay');
	if (!overlay) return;
	overlay.classList.remove('is-open');
	overlay.setAttribute('aria-hidden', 'true');
}

/**
 * AI Helpdesk Functions (async polling)
 */
function _gffcAiSleep(ms) {
	return new Promise(function(resolve) { setTimeout(resolve, ms); });
}

function _gffcAiGetRestUrl(path) {
	return (typeof wpApiSettings !== 'undefined' && wpApiSettings.root)
		? wpApiSettings.root + 'fflcockpit/v1/' + path
		: '/wp-json/fflcockpit/v1/' + path;
}

function _gffcAiGetNonce() {
	return (typeof wpApiSettings !== 'undefined' && wpApiSettings.nonce) ? wpApiSettings.nonce : '';
}

function _gffcAiRemoveTypingIndicator() {
	var el = document.getElementById('ai-typing-indicator');
	if (el) el.remove();
}

function _gffcAiShowResponse(messagesContainer, html, styleOverride) {
	var div = document.createElement('div');
	div.className = 'ai-message ai-assistant-message';
	if (styleOverride) {
		div.innerHTML = '<div class="ai-message-content" style="' + styleOverride + '">' + html + '</div>';
	} else {
		div.innerHTML = '<div class="ai-message-content">' + html + '</div>';
	}
	messagesContainer.appendChild(div);
	requestAnimationFrame(function () {
		var top = div.offsetTop - messagesContainer.offsetTop;
		messagesContainer.scrollTop = Math.max(0, top);
	});
	return div;
}

function _gffcAiResetControls() {
	var questionInput = document.getElementById('ai-question-input');
	var askButton = document.getElementById('ai-ask-button');
	var buttonText = document.getElementById('ai-ask-button-text');
	var spinner = document.getElementById('ai-ask-spinner');
	if (questionInput) questionInput.disabled = false;
	if (askButton) askButton.disabled = false;
	if (buttonText) buttonText.textContent = 'Ask';
	if (spinner) spinner.style.display = 'none';
	if (questionInput) questionInput.focus();
}

async function askAIHelpdesk() {
	var questionInput = document.getElementById('ai-question-input');
	var askButton = document.getElementById('ai-ask-button');
	var buttonText = document.getElementById('ai-ask-button-text');
	var spinner = document.getElementById('ai-ask-spinner');
	var messagesContainer = document.getElementById('ai-chat-messages');

	var question = questionInput.value.trim();
	if (!question) {
		alert('Please enter a question.');
		return;
	}

	// Disable input and show spinner
	questionInput.disabled = true;
	askButton.disabled = true;
	buttonText.textContent = 'Asking...';
	spinner.style.display = 'inline-block';

	// Add user message to chat
	var userMessageDiv = document.createElement('div');
	userMessageDiv.className = 'ai-message ai-user-message';
	userMessageDiv.innerHTML = '<div class="ai-message-content"><strong>You:</strong> ' + escapeHtml(question) + '</div>';
	messagesContainer.appendChild(userMessageDiv);

	// Add typing indicator
	var typingDiv = document.createElement('div');
	typingDiv.className = 'ai-message ai-assistant-message';
	typingDiv.id = 'ai-typing-indicator';
	typingDiv.innerHTML = '<div class="ai-typing-indicator"><span></span><span></span><span></span></div>';
	messagesContainer.appendChild(typingDiv);

	// Scroll to bottom
	messagesContainer.scrollTop = messagesContainer.scrollHeight;

	// Clear input
	questionInput.value = '';

	var nonce = _gffcAiGetNonce();

	try {
		// Step 1: Submit question (returns request_id immediately)
		var submitRes = await fetch(_gffcAiGetRestUrl('ai-helpdesk'), {
			method: 'POST',
			headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce },
			body: JSON.stringify({ question: question })
		});
		var submitData = await submitRes.json();

		// Handle rate limiting
		if (submitData.status === 'rate_limited') {
			_gffcAiRemoveTypingIndicator();
			var limitMsg = submitData.message || "You've reached your daily question limit. Please try again tomorrow.";
			if (submitData.usage) {
				limitMsg += ' (' + submitData.usage.question_count + '/' + submitData.usage.limit + ' used)';
			}
			_gffcAiShowResponse(messagesContainer, limitMsg, 'background: #fff8e1; color: #5d4037;');
			_gffcAiResetControls();
			return;
		}

		// Handle immediate errors (no request_id)
		if (submitData.error && !submitData.request_id) {
			_gffcAiRemoveTypingIndicator();
			_gffcAiShowResponse(messagesContainer, 'Sorry, I encountered an error: ' + escapeHtml(submitData.error), 'background: #ffebee; color: #c62828;');
			_gffcAiResetControls();
			return;
		}

		var requestId = submitData.request_id;
		if (!requestId) {
			// Fallback: if API returned a direct answer (old format), handle it
			_gffcAiRemoveTypingIndicator();
			var directAnswer = submitData.answer || submitData.response;
			if (directAnswer) {
				_gffcAiShowResponse(messagesContainer, formatAIResponse(directAnswer));
			} else {
				_gffcAiShowResponse(messagesContainer, 'I apologize, but I was unable to process your request. Please try again or contact support@garidium.com for help.');
			}
			_gffcAiResetControls();
			return;
		}

		// Step 2: Poll for result
		var maxAttempts = 30;
		var pollInterval = 1000;
		var hasShownProcessing = false;

		for (var i = 0; i < maxAttempts; i++) {
			await _gffcAiSleep(pollInterval);

			var pollRes = await fetch(_gffcAiGetRestUrl('ai-helpdesk-poll'), {
				method: 'POST',
				headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce },
				body: JSON.stringify({ request_id: requestId })
			});
			var pollData = await pollRes.json();

			// Update typing indicator text for processing state
			if (pollData.status === 'processing' && !hasShownProcessing) {
				hasShownProcessing = true;
				var indicator = document.getElementById('ai-typing-indicator');
				if (indicator) {
					indicator.innerHTML = '<div class="ai-typing-indicator"><span></span><span></span><span></span></div>';
				}
			}

			if (pollData.status === 'completed') {
				_gffcAiRemoveTypingIndicator();
				var result = pollData.result || {};
				var answer = result.answer || '';
				if (answer) {
					_gffcAiShowResponse(messagesContainer, formatAIResponse(answer));
				} else {
					_gffcAiShowResponse(messagesContainer, 'I apologize, but I was unable to find an answer to your question. Please try rephrasing or contact support@garidium.com for help.');
				}
				_gffcAiResetControls();
				return;
			}

			if (pollData.status === 'error') {
				_gffcAiRemoveTypingIndicator();
				var errMsg = pollData.error || 'An unknown error occurred.';
				_gffcAiShowResponse(messagesContainer, 'Sorry, I encountered an error: ' + escapeHtml(errMsg), 'background: #ffebee; color: #c62828;');
				_gffcAiResetControls();
				return;
			}

			// Still pending/processing — continue polling
		}

		// Timed out
		_gffcAiRemoveTypingIndicator();
		_gffcAiShowResponse(messagesContainer, 'The request took too long to process. Please try again or contact support@garidium.com for help.', 'background: #fff8e1; color: #5d4037;');
		_gffcAiResetControls();

	} catch (error) {
		console.error('AI Helpdesk error:', error);
		_gffcAiRemoveTypingIndicator();
		_gffcAiShowResponse(messagesContainer, 'Sorry, there was an error processing your request. Please try again later.', 'background: #ffebee; color: #c62828;');
		_gffcAiResetControls();
	}
}

function addAIKnowledge() {
	var questionInput = document.getElementById('ai-kb-question');
	var answerInput = document.getElementById('ai-kb-answer');
	var submitButton = document.getElementById('ai-kb-submit');
	var buttonText = document.getElementById('ai-kb-button-text');
	var spinner = document.getElementById('ai-kb-spinner');
	var statusSpan = document.getElementById('ai-kb-status');
	
	var question = questionInput.value.trim();
	var answer = answerInput.value.trim();
	
	if (!question || !answer) {
		statusSpan.textContent = 'Please fill in both question and answer.';
		statusSpan.style.color = '#c62828';
		return;
	}
	
	// Disable inputs and show spinner
	questionInput.disabled = true;
	answerInput.disabled = true;
	submitButton.disabled = true;
	buttonText.textContent = 'Adding...';
	spinner.style.display = 'inline-block';
	statusSpan.textContent = '';
	
	// Get REST API base URL from WordPress
	var restUrl = (typeof wpApiSettings !== 'undefined' && wpApiSettings.root) 
		? wpApiSettings.root + 'fflcockpit/v1/ai-knowledge'
		: '/wp-json/fflcockpit/v1/ai-knowledge';
	
	var nonce = (typeof wpApiSettings !== 'undefined' && wpApiSettings.nonce) 
		? wpApiSettings.nonce 
		: '';
	
	fetch(restUrl, {
		method: 'POST',
		headers: {
			'Content-Type': 'application/json',
			'X-WP-Nonce': nonce
		},
		body: JSON.stringify({ question: question, answer: answer })
	})
	.then(function(response) {
		return response.json();
	})
	.then(function(data) {
		if (data.success) {
			statusSpan.textContent = '✓ Successfully added to knowledge base!';
			statusSpan.style.color = '#2e7d32';
			questionInput.value = '';
			answerInput.value = '';
		} else {
			statusSpan.textContent = '✗ Error: ' + (data.error || 'Failed to add to knowledge base.');
			statusSpan.style.color = '#c62828';
		}
	})
	.catch(function(error) {
		console.error('AI Knowledge error:', error);
		statusSpan.textContent = '✗ Error: Failed to connect to server.';
		statusSpan.style.color = '#c62828';
	})
	.finally(function() {
		// Re-enable inputs
		questionInput.disabled = false;
		answerInput.disabled = false;
		submitButton.disabled = false;
		buttonText.textContent = 'Add to Knowledge Base';
		spinner.style.display = 'none';
	});
}

function escapeHtml(text) {
	var div = document.createElement('div');
	div.textContent = text;
	return div.innerHTML;
}

function formatAIResponse(text) {
	// Convert markdown-style formatting to HTML
	var formatted = escapeHtml(text);
	
	// Convert markdown headings
	formatted = formatted.replace(/^###\s*(.+)$/gm, '<h3 class="ai-md-h3">$1</h3>');
	formatted = formatted.replace(/^##\s*(.+)$/gm, '<h2 class="ai-md-h2">$1</h2>');
	formatted = formatted.replace(/^#\s*(.+)$/gm, '<h1 class="ai-md-h1">$1</h1>');
	
	// Convert **bold** to <strong>
	formatted = formatted.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
	
	// Convert *italic* to <em>
	formatted = formatted.replace(/\*([^*]+)\*/g, '<em>$1</em>');
	
	// Convert `code` to <code>
	formatted = formatted.replace(/`([^`]+)`/g, '<code>$1</code>');
	
	// Convert line breaks to <br>
	formatted = formatted.replace(/\n/g, '<br>');
	
	return formatted;
}

// Allow Enter key to submit question (Shift+Enter for new line)
document.addEventListener('DOMContentLoaded', function() {
	var aiQuestionInput = document.getElementById('ai-question-input');
	if (aiQuestionInput) {
		aiQuestionInput.addEventListener('keydown', function(e) {
			if (e.key === 'Enter' && !e.shiftKey) {
				e.preventDefault();
				askAIHelpdesk();
			}
		});
	}
});


