/**
 * Shortcode Generator — Admin UI logic.
 *
 * Handles:
 *  - Real-time shortcode string generation from form controls
 *  - Debounced AJAX preview of rendered widget
 *  - Copy-to-clipboard for generated shortcode
 *  - Conditional accent control visibility
 *
 * @since 0.1.0
 */
(function () {
	'use strict';

	const GENERATOR_CONFIG = window.crtodayShortcodeGeneratorConfig || {};
	const CTA_BUTTON_TEXT_DEFAULT = (GENERATOR_CONFIG.defaults || {}).ctaButtonText || '';

	/* ================================================================
	 * Constants
	 * ================================================================ */

	const SHARED_WIDGET_DEFAULTS = {
		intervalMin: '15',
		amount: '1',
		decimals: '2',
		theme: 'light',
		radius: '16',
		shadow: true,
		seamless: false,
		showFlags: true,
		attribution: true,
		compactMode: true,
		fitWidth: true,
		sourceLabel: '',
		showTimestamp: true,
		adjustmentPercent: '0',
		showCtaButton: false,
		ctaButtonText: CTA_BUTTON_TEXT_DEFAULT,
		ctaUrlTemplate: '',
		enableStructuredData: false,
		accentMode: 'stripe',
		accentTheme: 'default',
		accentAngle: '135',
	};

	const DEFAULTS = {
		source: 'FEX:DEFAULT',
		base: 'USD',
		symbols: 'EUR,GBP,JPY',
		invertRates: false,
		currencyLabelMode: 'code',
		showCurrencySymbols: false,
		showChange: false,
		...SHARED_WIDGET_DEFAULTS,
	};

	const CONVERTER_DEFAULTS = {
		source: 'FEX:DEFAULT',
		from: 'USD',
		to: 'EUR',
		...SHARED_WIDGET_DEFAULTS,
	};

	const DEBOUNCE_MS = 600;

	/* ================================================================
	 * State
	 * ================================================================ */

	let previewTimer = null;
	let currentXHR = null;
	let converterPreviewTimer = null;
	let converterCurrentXHR = null;

	/* ================================================================
	 * Init
	 * ================================================================ */

	function init() {
		initExchangeGenerator();
		initConverterGenerator();
		initAccentThemeSwatches();
	}

	function initExchangeGenerator() {
		const form = document.getElementById('crtoday-shortcode-form');
		if (!form) return;

		initSettingsTabs(form);

		/* Bind all controls */
		form.addEventListener('input', handleChange);
		form.addEventListener('change', handleChange);

		/* Range sliders — live value display */
		bindRangeDisplay('crtoday-sc-decimals', 'crtoday-decimals-value', '');
		bindRangeDisplay('crtoday-sc-radius', 'crtoday-radius-value', 'px');
		bindRangeDisplay('crtoday-sc-accentAngle', 'crtoday-accent-angle-value', '°');

		/* Tag-based currency input */
		initTagInput();

		/* Copy button */
		const copyBtn = document.getElementById('crtoday-copy-shortcode');
		if (copyBtn) {
			copyBtn.addEventListener('click', handleCopy);
		}

		/* Initial build */
		updateShortcodeOutput();
		requestPreview();
		updateAccentVisibility();
		updateCtaControlsState();
		updateSeamlessControlsState();
	}

	function initConverterGenerator() {
		const form = document.getElementById('crtoday-conv-shortcode-form');
		if (!form) return;

		initSettingsTabs(form);

		form.addEventListener('input', handleConverterChange);
		form.addEventListener('change', handleConverterChange);

		bindRangeDisplay('crtoday-conv-sc-decimals', 'crtoday-conv-decimals-value', '');
		bindRangeDisplay('crtoday-conv-sc-radius', 'crtoday-conv-radius-value', 'px');
		bindRangeDisplay('crtoday-conv-sc-accentAngle', 'crtoday-conv-accent-angle-value', '°');

		const copyBtn = document.getElementById('crtoday-conv-copy-shortcode');
		if (copyBtn) {
			copyBtn.addEventListener('click', handleConverterCopy);
		}

		updateConverterShortcodeOutput();
		requestConverterPreview();
		updateConverterAccentVisibility();
		updateConverterCtaControlsState();
		updateConverterSeamlessControlsState();
	}

	function initSettingsTabs(form) {
		const tabs = form.querySelector('[data-crtoday-settings-tabs]');
		if (!tabs) return;

		const buttons = Array.from(tabs.querySelectorAll('[data-crtoday-tab]'));
		const panes = Array.from(form.querySelectorAll('[data-crtoday-pane]'));
		if (buttons.length === 0 || panes.length === 0) return;

		function setActive(tabName) {
			buttons.forEach(function (button) {
				const isActive = button.getAttribute('data-crtoday-tab') === tabName;
				button.classList.toggle('button-primary', isActive);
				button.classList.toggle('button-secondary', !isActive);
			});

			panes.forEach(function (pane) {
				pane.style.display = pane.getAttribute('data-crtoday-pane') === tabName ? '' : 'none';
			});
		}

		buttons.forEach(function (button) {
			button.addEventListener('click', function () {
				setActive(button.getAttribute('data-crtoday-tab'));
			});
		});

		setActive(buttons[0].getAttribute('data-crtoday-tab'));
	}

	function bindRangeDisplay(inputId, displayId, suffix) {
		var input = document.getElementById(inputId);
		var display = document.getElementById(displayId);
		if (input && display) {
			input.addEventListener('input', function () {
				display.textContent = input.value + suffix;
			});
		}
	}

	function initAccentThemeSwatches() {
		document.querySelectorAll('[data-crtoday-theme-grid]').forEach(function (grid) {
			var targetSelector = grid.getAttribute('data-crtoday-theme-target');
			if (!targetSelector) return;

			var input = document.querySelector(targetSelector);
			if (!input) return;

			var buttons = Array.from(grid.querySelectorAll('[data-crtoday-theme-value]'));

			function setActive(value) {
				buttons.forEach(function (btn) {
					var isActive = btn.getAttribute('data-crtoday-theme-value') === value;
					btn.classList.toggle('is-active', isActive);
				});
			}

			setActive(input.value);

			buttons.forEach(function (btn) {
				btn.addEventListener('click', function () {
					var nextValue = btn.getAttribute('data-crtoday-theme-value');
					if (!nextValue) return;

					input.value = nextValue;
					setActive(nextValue);
					input.dispatchEvent(new Event('input', { bubbles: true }));
					input.dispatchEvent(new Event('change', { bubbles: true }));
				});
			});
		});
	}

	/* ================================================================
	 * Tag-based currency input (legacy - now handled by currency-picker.js)
	 * ================================================================ */

	function initTagInput() {
		/* Multi-picker is now handled by currency-picker.js.
		 * Events bubble up to form and trigger handleChange(). */
	}

	/* ================================================================
	 * Event handlers
	 * ================================================================ */

	function handleChange() {
		updateShortcodeOutput();
		updateAccentVisibility();
		updateCtaControlsState();
		updateSeamlessControlsState();
		debouncePreview();
	}

	function handleConverterChange() {
		updateConverterShortcodeOutput();
		updateConverterAccentVisibility();
		updateConverterCtaControlsState();
		updateConverterSeamlessControlsState();
		debounceConverterPreview();
	}

	function copyFromOutput(outputId, buttonId) {
		const output = document.getElementById(outputId);
		if (!output) return;

		const text = output.textContent || output.innerText;
		if (navigator.clipboard && navigator.clipboard.writeText) {
			navigator.clipboard.writeText(text).then(function () {
				flashCopyFeedback(buttonId);
			});
			return;
		}

		const ta = document.createElement('textarea');
		ta.value = text;
		ta.style.position = 'fixed';
		ta.style.opacity = '0';
		document.body.appendChild(ta);
		ta.select();
		document.execCommand('copy');
		document.body.removeChild(ta);
		flashCopyFeedback(buttonId);
	}

	function handleCopy() {
		copyFromOutput('crtoday-shortcode-output', 'crtoday-copy-shortcode');
	}

	function handleConverterCopy() {
		copyFromOutput('crtoday-conv-shortcode-output', 'crtoday-conv-copy-shortcode');
	}

	function flashCopyFeedback(buttonId) {
		const btn = document.getElementById(buttonId);
		if (!btn) return;
		const orig = btn.textContent;
		btn.textContent = btn.getAttribute('data-copied-label') || orig;
		btn.disabled = true;
		setTimeout(function () {
			btn.textContent = orig;
			btn.disabled = false;
		}, 1500);
	}

	/* ================================================================
	 * Shortcode string generation
	 * ================================================================ */

	function gatherAttributesFromForm(formId, attrSelector) {
		const form = document.getElementById(formId);
		if (!form) return {};

		const attrs = {};
		form.querySelectorAll(attrSelector).forEach(function (el) {
			const key = el.getAttribute('data-attr') || el.getAttribute('data-conv-attr');
			if (!key) return;
			if (el.type === 'checkbox') {
				attrs[key] = el.checked;
			} else {
				attrs[key] = el.value;
			}
		});
		return attrs;
	}

	function gatherAttributes() {
		return gatherAttributesFromForm('crtoday-shortcode-form', 'input[data-attr], select[data-attr]');
	}

	function buildShortcodeForTag(attrs, defaults, shortcodeTag) {
		let parts = ['[' + shortcodeTag];

		for (const [key, val] of Object.entries(attrs)) {
			const def = defaults[key];

			/* Skip attributes that match defaults */
			if (def !== undefined) {
				if (typeof def === 'boolean' && val === def) continue;
				if (typeof def !== 'boolean' && String(val) === String(def)) continue;
			}

			/* Format value */
			if (typeof val === 'boolean') {
				parts.push(key + '="' + (val ? 'true' : 'false') + '"');
			} else {
				parts.push(key + '="' + String(val).replace(/"/g, '\\"') + '"');
			}
		}

		parts.push(']');
		return parts.join(' ');
	}

	function buildShortcode(attrs) {
		return buildShortcodeForTag(attrs, DEFAULTS, 'crtoday_exchange_rates');
	}

	function updateShortcodeOutput() {
		const attrs = gatherAttributes();
		const code = buildShortcode(attrs);
		const output = document.getElementById('crtoday-shortcode-output');
		if (output) {
			output.textContent = code;
		}
	}

	function gatherConverterAttributes() {
		return gatherAttributesFromForm('crtoday-conv-shortcode-form', 'input[data-conv-attr], select[data-conv-attr]');
	}

	function buildConverterShortcode(attrs) {
		return buildShortcodeForTag(attrs, CONVERTER_DEFAULTS, 'crtoday_currency_converter');
	}

	function updateConverterShortcodeOutput() {
		const attrs = gatherConverterAttributes();
		const code = buildConverterShortcode(attrs);
		const output = document.getElementById('crtoday-conv-shortcode-output');
		if (output) {
			output.textContent = code;
		}
	}

	/* ================================================================
	 * Accent visibility
	 * ================================================================ */



	function updateAccentVisibility() {
		const mode = document.querySelector('[data-attr="accentMode"]');
		if (!mode) return;

		const val = mode.value;
		const angleRow = document.getElementById('crtoday-row-accentAngle');

		if (angleRow) {
			angleRow.style.display = (val === 'stripe') ? '' : 'none';
		}
	}

	function updateConverterAccentVisibility() {
		const form = document.getElementById('crtoday-conv-shortcode-form');
		if (!form) return;

		const mode = form.querySelector('[data-conv-attr="accentMode"]');
		if (!mode) return;

		const val = mode.value;
		const angleRow = document.getElementById('crtoday-conv-row-accentAngle');

		if (angleRow) {
			angleRow.style.display = (val === 'stripe') ? '' : 'none';
		}
	}

	function updateCtaControlsState() {
		const form = document.getElementById('crtoday-shortcode-form');
		if (!form) return;

		const enabledEl = form.querySelector('[data-attr="showCtaButton"]');
		const textEl = form.querySelector('[data-attr="ctaButtonText"]');
		const urlEl = form.querySelector('[data-attr="ctaUrlTemplate"]');
		if (!enabledEl || !textEl || !urlEl) return;

		const enabled = enabledEl.checked;
		textEl.disabled = !enabled;
		urlEl.disabled = !enabled;
	}

	function updateConverterCtaControlsState() {
		const form = document.getElementById('crtoday-conv-shortcode-form');
		if (!form) return;

		const enabledEl = form.querySelector('[data-conv-attr="showCtaButton"]');
		const textEl = form.querySelector('[data-conv-attr="ctaButtonText"]');
		const urlEl = form.querySelector('[data-conv-attr="ctaUrlTemplate"]');
		if (!enabledEl || !textEl || !urlEl) return;

		const enabled = enabledEl.checked;
		textEl.disabled = !enabled;
		urlEl.disabled = !enabled;
	}

	/* ================================================================
	 * Seamless mode — disable visual controls
	 * ================================================================ */

	function updateSeamlessControlsState() {
		const form = document.getElementById('crtoday-shortcode-form');
		if (!form) return;

		const seamlessEl = form.querySelector('[data-attr="seamless"]');
		if (!seamlessEl) return;

		const isSeamless = seamlessEl.checked;

		/* Disable theme, shadow, radius controls */
		const themeEl = form.querySelector('[data-attr="theme"]');
		const shadowEl = form.querySelector('[data-attr="shadow"]');
		const radiusEl = form.querySelector('[data-attr="radius"]');
		if (themeEl) themeEl.disabled = isSeamless;
		if (shadowEl) shadowEl.disabled = isSeamless;
		if (radiusEl) radiusEl.disabled = isSeamless;

		/* Disable all style controls when seamless is enabled */
		const accentModeEl = form.querySelector('[data-attr="accentMode"]');
		const accentThemeEl = form.querySelector('[data-attr="accentTheme"]');
		const accentAngleEl = form.querySelector('[data-attr="accentAngle"]');
		if (accentModeEl) accentModeEl.disabled = isSeamless;
		if (accentThemeEl) accentThemeEl.disabled = isSeamless;
		if (accentAngleEl) accentAngleEl.disabled = isSeamless;

		form
			.querySelectorAll('[data-crtoday-theme-target="#crtoday-sc-accentTheme"] [data-crtoday-theme-value]')
			.forEach(function (button) {
				button.disabled = isSeamless;
			});
	}

	function updateConverterSeamlessControlsState() {
		const form = document.getElementById('crtoday-conv-shortcode-form');
		if (!form) return;

		const seamlessEl = form.querySelector('[data-conv-attr="seamless"]');
		if (!seamlessEl) return;

		const isSeamless = seamlessEl.checked;

		/* Disable theme, shadow, radius controls */
		const themeEl = form.querySelector('[data-conv-attr="theme"]');
		const shadowEl = form.querySelector('[data-conv-attr="shadow"]');
		const radiusEl = form.querySelector('[data-conv-attr="radius"]');
		if (themeEl) themeEl.disabled = isSeamless;
		if (shadowEl) shadowEl.disabled = isSeamless;
		if (radiusEl) radiusEl.disabled = isSeamless;

		/* Disable all style controls when seamless is enabled */
		const accentModeEl = form.querySelector('[data-conv-attr="accentMode"]');
		const accentThemeEl = form.querySelector('[data-conv-attr="accentTheme"]');
		const accentAngleEl = form.querySelector('[data-conv-attr="accentAngle"]');
		if (accentModeEl) accentModeEl.disabled = isSeamless;
		if (accentThemeEl) accentThemeEl.disabled = isSeamless;
		if (accentAngleEl) accentAngleEl.disabled = isSeamless;

		form
			.querySelectorAll('[data-crtoday-theme-target="#crtoday-conv-sc-accentTheme"] [data-crtoday-theme-value]')
			.forEach(function (button) {
				button.disabled = isSeamless;
			});
	}

	/* ================================================================
	 * AJAX Preview
	 * ================================================================ */

	function debouncePreview() {
		if (previewTimer) clearTimeout(previewTimer);
		previewTimer = setTimeout(requestPreview, DEBOUNCE_MS);
	}

	function debounceConverterPreview() {
		if (converterPreviewTimer) clearTimeout(converterPreviewTimer);
		converterPreviewTimer = setTimeout(requestConverterPreview, DEBOUNCE_MS);
	}

	function requestPreviewByConfig(config) {
		const container = document.getElementById(config.containerId);
		if (!container) return;

		const attrs = config.gatherAttributes();
		const nonce = document.getElementById(config.nonceId);
		if (!nonce) return;

		if (config.getXhr()) {
			config.getXhr().abort();
		}

		container.classList.add('crtoday-preview-loading');

		const formData = new FormData();
		formData.append('action', config.action);
		formData.append('nonce', nonce.value);

		for (const [key, val] of Object.entries(attrs)) {
			formData.append('attributes[' + key + ']', typeof val === 'boolean' ? (val ? '1' : '0') : String(val));
		}

		const xhr = new XMLHttpRequest();
		config.setXhr(xhr);
		xhr.open('POST', window.ajaxurl, true);
		xhr.onreadystatechange = function () {
			if (xhr.readyState !== 4) return;

			container.classList.remove('crtoday-preview-loading');

			if (xhr.status === 200) {
				try {
					const resp = JSON.parse(xhr.responseText);
					if (resp.success && resp.data && resp.data.html) {
						container.innerHTML = resp.data.html;
					}
				} catch (_error) {
					/* Ignore parse errors */
				}
			}
			config.setXhr(null);
		};
		xhr.send(formData);
	}

	function requestPreview() {
		requestPreviewByConfig({
			containerId: 'crtoday-shortcode-preview',
			nonceId: 'crtoday-preview-nonce',
			action: 'crtoday_shortcode_preview',
			gatherAttributes: gatherAttributes,
			getXhr: function () { return currentXHR; },
			setXhr: function (xhr) { currentXHR = xhr; },
		});
	}

	function requestConverterPreview() {
		requestPreviewByConfig({
			containerId: 'crtoday-conv-shortcode-preview',
			nonceId: 'crtoday-conv-preview-nonce',
			action: 'crtoday_currency_converter_shortcode_preview',
			gatherAttributes: gatherConverterAttributes,
			getXhr: function () { return converterCurrentXHR; },
			setXhr: function (xhr) { converterCurrentXHR = xhr; },
		});
	}

	/* ================================================================
	 * Boot
	 * ================================================================ */

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init);
	} else {
		init();
	}
})();
