/**
 * Answyr — customer portal.
 * Logged-in customers see their tickets, read the thread, reply, resolve/reopen.
 */
(() => {
	var cfg = window.AnswyrPortal;
	var root = document.getElementById('answyr-portal');
	if (!cfg || !root) {
		return;
	}

	var allTickets = [];
	var filter = 'all'; // all | open | closed

	function api(path, options) {
		var opts = options || {};
		opts.headers = Object.assign(
			{ 'Content-Type': 'application/json', 'X-WP-Nonce': cfg.nonce },
			opts.headers || {},
		);
		return fetch(cfg.restBase + path, opts).then((r) =>
			r.json().then((data) => ({ ok: r.ok, data: data })),
		);
	}

	function esc(text) {
		var d = document.createElement('div');
		d.textContent = text == null ? '' : text;
		return d.innerHTML;
	}

	// open + pending are "Open"; resolved + closed are "Closed".
	function groupOf(status) {
		return status === 'open' || status === 'pending' ? 'open' : 'closed';
	}

	function label(status) {
		return status ? status.charAt(0).toUpperCase() + status.slice(1) : '';
	}

	function listHeader() {
		var who = cfg.user ? `<span class="ssp-whoami">${esc(cfg.user)}</span>` : '';
		var logout = cfg.logoutUrl
			? `<a class="ssp-logout" href="${esc(cfg.logoutUrl)}">Log out</a>`
			: '';
		return `<div class="ssp-head">
			<h3>Your support requests</h3>
			<div class="ssp-head-actions">
				${who}${logout}
				<button type="button" class="ssp-new-btn">+ New request</button>
			</div>
		</div>`;
	}

	function tabs() {
		var counts = { all: allTickets.length, open: 0, closed: 0 };
		allTickets.forEach((t) => {
			counts[groupOf(t.status)] += 1;
		});
		var defs = [
			['all', 'All'],
			['open', 'Open'],
			['closed', 'Closed'],
		];
		var items = defs
			.map(
				([key, text]) =>
					`<button type="button" class="ssp-tab${key === filter ? ' is-active' : ''}" data-filter="${key}">${text} (${counts[key]})</button>`,
			)
			.join('');
		return `<div class="ssp-tabs">${items}</div>`;
	}

	function wireHeader() {
		var btn = root.querySelector('.ssp-new-btn');
		if (btn) {
			btn.addEventListener('click', showCreate);
		}
		root.querySelectorAll('.ssp-tab').forEach((tab) => {
			tab.addEventListener('click', () => {
				filter = tab.getAttribute('data-filter');
				renderList();
			});
		});
	}

	function renderList() {
		var shown =
			filter === 'all' ? allTickets : allTickets.filter((t) => groupOf(t.status) === filter);

		var body;
		var rows;
		if (!shown.length) {
			body = `<p class="ssp-empty">${allTickets.length ? 'Nothing here.' : 'You have no support requests yet.'}</p>`;
		} else {
			rows = shown
				.map(
					(t) =>
						`<li class="ssp-item" data-id="${t.id}">
							<button type="button" class="ssp-open">
								<span class="ssp-subject">${esc(t.subject)}</span>
								<span class="ssp-status ssp-status-${esc(t.status)}">${esc(label(t.status))}</span>
								<span class="ssp-date">${esc(t.updated_at)}</span>
							</button>
						</li>`,
				)
				.join('');
			body = `<ul class="ssp-list">${rows}</ul>`;
		}

		root.innerHTML = `${listHeader()}${tabs()}${body}`;
		wireHeader();
		root.querySelectorAll('.ssp-item').forEach((li) => {
			li.querySelector('.ssp-open').addEventListener('click', () =>
				showThread(li.getAttribute('data-id')),
			);
		});
	}

	function showList() {
		root.innerHTML = '<p class="ssp-loading">Loading…</p>';
		api('/tickets').then((res) => {
			if (!res.ok) {
				root.innerHTML = `<p>${esc(res.data?.error || 'Could not load tickets.')}</p>`;
				return;
			}
			allTickets = res.data || [];
			renderList();
		});
	}

	function fieldsMarkup() {
		return (cfg.intakeFields || [])
			.map((f) => {
				var required = f.required ? ' required' : '';
				var star = f.required ? ' <span class="answyr-req" aria-hidden="true">*</span>' : '';
				var control =
					f.type === 'textarea'
						? `<textarea class="ssp-field" data-key="${esc(f.key)}" rows="3"${required}></textarea>`
						: `<input type="${esc(f.type)}" class="ssp-field" data-key="${esc(f.key)}"${required}>`;
				return `<label class="ssp-field-label">${esc(f.label)}${star}</label>${control}`;
			})
			.join('');
	}

	function showCreate() {
		root.innerHTML = `
			<button type="button" class="ssp-back">← Back</button>
			<h3>New request</h3>
			<div class="ssp-create">
				<input type="text" class="ssp-new-subject" placeholder="Subject (optional)">
				<textarea class="ssp-new-body" rows="5" placeholder="How can we help?"></textarea>
				${fieldsMarkup()}
				<button type="button" class="ssp-new-send">Submit request</button>
				<span class="ssp-new-status"></span>
			</div>`;
		root.querySelector('.ssp-back').addEventListener('click', showList);
		root.querySelector('.ssp-new-send').addEventListener('click', submitCreate);
	}

	function submitCreate() {
		var subject = root.querySelector('.ssp-new-subject').value.trim();
		var body = root.querySelector('.ssp-new-body').value.trim();
		var status = root.querySelector('.ssp-new-status');
		if (!body) {
			status.textContent = 'Please describe your request.';
			return;
		}
		var fields = {};
		root.querySelectorAll('.ssp-field').forEach((el) => {
			fields[el.getAttribute('data-key')] = el.value;
		});
		status.textContent = 'Submitting…';
		api('/tickets', {
			method: 'POST',
			body: JSON.stringify({ subject: subject, message: body, fields: fields }),
		}).then((res) => {
			if (!res.ok || res.data.error) {
				status.textContent = res.data?.error || 'Failed.';
				return;
			}
			showThread(res.data.ticket_id);
		});
	}

	function showThread(id) {
		root.innerHTML = '<p class="ssp-loading">Loading…</p>';
		api(`/tickets/${id}`).then((res) => {
			if (!res.ok) {
				root.innerHTML = `<p>${esc(res.data?.error || 'Could not load ticket.')}</p>`;
				return;
			}
			var t = res.data;
			var msgs = (t.messages || [])
				.map(
					(m) =>
						`<div class="ssp-msg ssp-msg-${m.author === 'You' ? 'you' : 'support'}">
							<div class="ssp-msg-meta">${esc(m.author)} · ${esc(m.created_at)}</div>
							<div class="ssp-msg-body">${m.html ? m.body : window.AnswyrMD ? window.AnswyrMD.render(m.body) : esc(m.body)}</div>
						</div>`,
				)
				.join('');
			var closed = groupOf(t.status) === 'closed';
			var toggle = closed
				? '<button type="button" class="ssp-reopen">Reopen request</button>'
				: '<button type="button" class="ssp-resolve">Mark as resolved</button>';
			root.innerHTML = `
				<button type="button" class="ssp-back">← Back</button>
				<h3>${esc(t.subject)} <span class="ssp-status ssp-status-${esc(t.status)}">${esc(label(t.status))}</span></h3>
				<div class="ssp-thread">${msgs}</div>
				${attachmentsBlock(t)}
				${csatBlock(closed, t.rating)}
				<div class="ssp-reply">
					<textarea class="ssp-reply-body" rows="4" placeholder="Add a reply…"></textarea>
					<div class="ssp-reply-actions">
						<button type="button" class="ssp-reply-send">Send reply</button>
						${toggle}
						<span class="ssp-reply-status"></span>
					</div>
				</div>`;
			root.querySelector('.ssp-back').addEventListener('click', showList);
			root.querySelector('.ssp-reply-send').addEventListener('click', () => sendReply(id));
			var resolveBtn = root.querySelector('.ssp-resolve');
			var reopenBtn = root.querySelector('.ssp-reopen');
			if (resolveBtn) {
				resolveBtn.addEventListener('click', () => setStatus(id, 'resolved'));
			}
			if (reopenBtn) {
				reopenBtn.addEventListener('click', () => setStatus(id, 'open'));
			}
			root.querySelectorAll('.ssp-rate').forEach((btn) => {
				btn.addEventListener('click', () => rate(id, Number(btn.getAttribute('data-rating'))));
			});
		});
	}

	// Ticket attachments (Pro). Renders the download list from server data, plus an
	// upload control when the Pro upload script is present (portal-attachments.js).
	function attachmentsBlock(t) {
		var canAttach = !!window.AnswyrPortalAttach;
		var items = (t.attachments || [])
			.map(
				(a) =>
					`<li><a href="${esc(a.url)}" rel="noopener">${esc(a.name)}</a> <span class="ssp-attach-size">${esc(a.size)}</span></li>`,
			)
			.join('');
		if (!items && !canAttach) {
			return '';
		}
		var uploader = canAttach
			? `<p class="ssp-attach-add"><input type="file" class="ssp-attach-file" data-id="${t.id}"><span class="ssp-attach-status"></span></p>`
			: '';
		return `<div class="ssp-attachments"><h4>Attachments</h4><ul class="ssp-attach-list">${items}</ul>${uploader}</div>`;
	}

	// Satisfaction prompt — shown on closed/resolved tickets that aren't rated yet.
	function csatBlock(closed, rating) {
		if (!closed) {
			return '';
		}
		if (rating) {
			return `<div class="ssp-csat ssp-csat-done">${rating >= 4 ? '👍' : '👎'} Thanks for your feedback.</div>`;
		}
		return `<div class="ssp-csat">
			<span>How was your support experience?</span>
			<button type="button" class="ssp-rate" data-rating="5" aria-label="Good">👍</button>
			<button type="button" class="ssp-rate" data-rating="1" aria-label="Bad">👎</button>
		</div>`;
	}

	function rate(id, rating) {
		api(`/tickets/${id}/rate`, { method: 'POST', body: JSON.stringify({ rating: rating }) }).then(
			() => showThread(id),
		);
	}

	function setStatus(id, status) {
		var note = root.querySelector('.ssp-reply-status');
		if (note) {
			note.textContent = 'Updating…';
		}
		api(`/tickets/${id}/status`, { method: 'POST', body: JSON.stringify({ status: status }) }).then(
			(res) => {
				if (!res.ok || res.data.error) {
					if (note) {
						note.textContent = res.data?.error || 'Failed.';
					}
					return;
				}
				showThread(id);
			},
		);
	}

	function sendReply(id) {
		var body = root.querySelector('.ssp-reply-body').value.trim();
		var status = root.querySelector('.ssp-reply-status');
		if (!body) {
			status.textContent = 'Write a message first.';
			return;
		}
		status.textContent = 'Sending…';
		api(`/tickets/${id}/reply`, { method: 'POST', body: JSON.stringify({ body: body }) }).then(
			(res) => {
				if (!res.ok) {
					status.textContent = res.data?.error || 'Failed.';
					return;
				}
				showThread(id);
			},
		);
	}

	showList();
})();
