/**
 * Answyr Chat — deflection widget.
 * Asks the shared AI core (one JSON request/response — not streaming) and offers
 * human escalation that opens a Desk ticket with the transcript.
 */
(() => {
	var cfg = window.AnswyrChat;
	if (!cfg) {
		return;
	}

	// Inline SVG (not an emoji) so the launcher icon renders identically across
	// themes — some theme button resets blank out emoji glyphs. `currentColor`
	// lets us tint it to contrast with the configured accent.
	var CHAT_ICON =
		'<svg class="answyr-chat-launcher-icon" width="26" height="26" viewBox="0 0 24 24" aria-hidden="true" focusable="false">' +
		'<path fill="currentColor" d="M12 3C6.48 3 2 6.58 2 11c0 2.05.98 3.9 2.6 5.32-.13 1.3-.6 2.5-1.37 3.53-.24.32.02.79.42.7 1.94-.34 3.4-.98 4.45-1.7 1.2.42 2.5.65 3.9.65 5.52 0 10-3.58 10-8s-4.48-8-10-8z"/></svg>';

	var history = [];
	// One id per widget load groups a visitor's questions into a "session" so Pro
	// analytics can measure deflection (a session that never escalates = deflected).
	var sessionId =
		(window.crypto && crypto.randomUUID && crypto.randomUUID()) ||
		Date.now().toString(36) + Math.random().toString(36).slice(2);
	var root = buildUI();
	document.body.appendChild(root.launcher);
	document.body.appendChild(root.panel);

	function buildUI() {
		// One foreground color that reads on the configured accent, used everywhere
		// we place content on the accent (launcher icon, header text).
		var fg = contrastColor(cfg.primaryColor);

		var launcher = el('button', 'answyr-chat-launcher');
		launcher.type = 'button';
		launcher.innerHTML = CHAT_ICON;
		launcher.style.background = cfg.primaryColor;
		launcher.style.color = fg;
		launcher.setAttribute('aria-label', cfg.title);

		var panel = el('div', 'answyr-chat-panel');
		panel.hidden = true;
		// Drive the whole widget accent (send button, user bubbles, sources, escalate)
		// off the configured color, not just the launcher/header.
		panel.style.setProperty('--answyr-accent', cfg.primaryColor);

		var header = el('div', 'answyr-chat-header');
		header.style.background = cfg.primaryColor;
		header.style.color = fg;
		var title = el('span', 'answyr-chat-title', cfg.title);
		var minimize = el('button', 'answyr-chat-min', '–');
		minimize.type = 'button';
		minimize.style.color = fg;
		minimize.setAttribute('aria-label', 'Minimize');
		header.appendChild(title);
		header.appendChild(minimize);

		var log = el('div', 'answyr-chat-log');
		addMsg(log, 'assistant', cfg.welcome);

		var form = el('form', 'answyr-chat-form');
		var input = el('input', 'answyr-chat-input');
		input.placeholder = cfg.placeholder;
		input.setAttribute('aria-label', cfg.placeholder);
		var send = el('button', 'answyr-chat-send', '→');
		send.type = 'submit';
		form.appendChild(input);
		form.appendChild(send);

		// Only offer "create a ticket" when the Desk (ticketing) surface is enabled.
		var escalate = null;
		if (cfg.canEscalate) {
			escalate = el('button', 'answyr-chat-escalate', cfg.escalateLabel);
			escalate.type = 'button';
		}

		panel.appendChild(header);
		panel.appendChild(log);
		if (escalate) {
			panel.appendChild(escalate);
		}
		panel.appendChild(form);

		launcher.addEventListener('click', () => {
			panel.hidden = !panel.hidden;
			if (!panel.hidden) {
				input.focus();
			}
		});

		minimize.addEventListener('click', () => {
			panel.hidden = true;
		});

		form.addEventListener('submit', (e) => {
			e.preventDefault();
			var q = input.value.trim();
			if (!q) {
				return;
			}
			input.value = '';
			ask(log, q);
		});

		if (escalate) {
			escalate.addEventListener('click', () => {
				openEscalation(log);
			});
		}

		return { launcher: launcher, panel: panel, log: log };
	}

	function ask(log, question) {
		addMsg(log, 'user', question);
		history.push({ role: 'user', content: question });
		var bubble = addMsg(log, 'assistant', '');
		bubble.classList.add('answyr-chat-thinking');
		bubble.innerHTML = '<span class="answyr-typing"><span></span><span></span><span></span></span>';

		var clearThinking = () => {
			bubble.classList.remove('answyr-chat-thinking');
			bubble.textContent = '';
		};

		fetch(cfg.endpoint, {
			method: 'POST',
			headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': cfg.nonce },
			body: JSON.stringify({
				question: question,
				history: history.slice(0, -1),
				session_id: sessionId,
			}),
		})
			.then((resp) =>
				resp.json().then((data) => ({ ok: resp.ok, status: resp.status, data: data })),
			)
			.then((res) => {
				clearThinking();
				if (!res.ok || res.data.error) {
					bubble.textContent = res.data.error || 'Something went wrong. Please try again.';
					return;
				}
				var answer = res.data.answer || '';
				if (window.AnswyrMD) {
					bubble.innerHTML = window.AnswyrMD.render(answer);
				} else {
					bubble.textContent = answer;
				}
				history.push({ role: 'assistant', content: answer });
				if (res.data.sources?.length) {
					renderSources(bubble, res.data.sources);
				}
				log.scrollTop = log.scrollHeight;
			})
			.catch((e) => {
				clearThinking();
				bubble.textContent = e.message;
			});
	}

	function openEscalation(log) {
		var hasTranscript = history.length > 0;
		var wrap = el('div', 'answyr-chat-escalate-form');
		var transcriptRow = hasTranscript
			? '<label class="answyr-esc-transcript"><input type="checkbox" class="answyr-esc-include" checked> Include chat transcript</label>'
			: '';
		wrap.innerHTML =
			'<input type="email" placeholder="Your email" class="answyr-esc-email">' +
			'<textarea placeholder="Describe your issue" class="answyr-esc-msg" rows="3"></textarea>' +
			transcriptRow +
			'<button type="button" class="answyr-esc-submit">Create ticket</button>' +
			'<span class="answyr-esc-status"></span>';
		log.appendChild(wrap);
		log.scrollTop = log.scrollHeight;

		// Logged-in: lock the email to the account (ticket is tied to it).
		var emailInput = wrap.querySelector('.answyr-esc-email');
		if (cfg.userEmail) {
			emailInput.value = cfg.userEmail;
			emailInput.readOnly = true;
			emailInput.title = 'Using your account email';
		}

		wrap.querySelector('.answyr-esc-submit').addEventListener('click', () => {
			var email = emailInput.value.trim();
			var msg = wrap.querySelector('.answyr-esc-msg').value.trim();
			var includeEl = wrap.querySelector('.answyr-esc-include');
			var include = includeEl ? includeEl.checked : false;
			var status = wrap.querySelector('.answyr-esc-status');

			if (!email) {
				status.textContent = 'Email is required.';
				return;
			}
			// A description is only required when no transcript is being attached.
			if (!msg && !(include && hasTranscript)) {
				status.textContent = 'Please describe your issue.';
				return;
			}

			var submitBtn = wrap.querySelector('.answyr-esc-submit');
			submitBtn.disabled = true;
			status.textContent = 'Sending…';
			fetch(cfg.escalateUrl, {
				method: 'POST',
				headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': cfg.nonce },
				body: JSON.stringify({
					email: email,
					message: msg,
					history: include ? history : [],
					session_id: sessionId,
				}),
			})
				.then((r) => r.json())
				.then((data) => {
					if (data.ok) {
						showConfirmation(log, wrap, data.ticket_id);
					} else {
						submitBtn.disabled = false;
						status.textContent = data.error || 'Failed';
					}
				})
				.catch((e) => {
					submitBtn.disabled = false;
					status.textContent = e.message;
				});
		});
	}

	// Replace the escalation form with a clear "ticket created" confirmation and
	// pause the chat compose row — the thread is now a ticket, handled by email
	// + the portal. "Ask another question" returns to the live chat.
	function showConfirmation(log, wrap, ticketId) {
		var panel = log.closest('.answyr-chat-panel');
		var form = panel?.querySelector('.answyr-chat-form');
		var escalate = panel?.querySelector('.answyr-chat-escalate');
		if (form) {
			form.hidden = true;
		}
		if (escalate) {
			escalate.hidden = true;
		}

		var ref = Number(ticketId) > 0 ? `#${Number(ticketId)}` : '';
		var note = cfg.portalUrl
			? "We've emailed you a confirmation. Track its progress and reply any time in the support portal."
			: "We've emailed you a confirmation with your reference number. Our team will get back to you by email.";
		var ctaLabel = cfg.userEmail ? 'View your tickets →' : 'Open the support portal →';
		var cta = cfg.portalUrl
			? `<a class="answyr-chat-confirm-cta" href="${cfg.portalUrl}" target="_blank" rel="noopener">${ctaLabel}</a>`
			: '';

		wrap.className = 'answyr-chat-confirm';
		wrap.innerHTML =
			'<div class="answyr-chat-confirm-icon" aria-hidden="true">✓</div>' +
			'<div class="answyr-chat-confirm-title">Ticket created</div>' +
			(ref ? `<div class="answyr-chat-confirm-ref">Reference ${ref}</div>` : '') +
			`<p class="answyr-chat-confirm-note">${note}</p>` +
			cta +
			'<button type="button" class="answyr-chat-confirm-again">Ask another question</button>';
		log.scrollTop = log.scrollHeight;

		wrap.querySelector('.answyr-chat-confirm-again').addEventListener('click', () => {
			wrap.remove();
			var input = form?.querySelector('.answyr-chat-input');
			if (form) {
				form.hidden = false;
			}
			if (input) {
				input.focus();
			}
			if (escalate) {
				escalate.hidden = false;
			}
		});
	}

	function renderSources(bubble, sources) {
		var box = el('div', 'answyr-chat-sources');
		sources.forEach((s) => {
			var a = document.createElement('a');
			a.href = s.url;
			a.target = '_blank';
			a.rel = 'noopener';
			a.textContent = s.title || s.url;
			box.appendChild(a);
		});
		bubble.appendChild(box);
	}

	function addMsg(log, who, text) {
		var msg = el('div', `answyr-chat-msg answyr-chat-${who}`, text);
		log.appendChild(msg);
		log.scrollTop = log.scrollHeight;
		return msg;
	}

	// Pick black or white for content sitting on the given accent color, so the
	// launcher icon and header text stay legible whatever accent the admin sets.
	function contrastColor(hex) {
		var c = String(hex || '')
			.trim()
			.replace('#', '');
		if (c.length === 3) {
			c = c[0] + c[0] + c[1] + c[1] + c[2] + c[2];
		}
		if (c.length !== 6) {
			return '#fff';
		}
		var r = parseInt(c.slice(0, 2), 16);
		var g = parseInt(c.slice(2, 4), 16);
		var b = parseInt(c.slice(4, 6), 16);
		var luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
		return luminance > 0.6 ? '#111' : '#fff';
	}

	function el(tag, cls, text) {
		var node = document.createElement(tag);
		node.className = cls;
		if (text !== undefined) {
			node.textContent = text;
		}
		return node;
	}
})();
