/**
 * Pure FAQ item list helpers (insert / edit / remove / reorder).
 */

import { createItemId, isValidUuid } from './uuid';

/**
 * @return {{id:string,question:string,answer:string}} Empty FAQ row.
 */
export function createEmptyItem() {
	return {
		id: createItemId(),
		question: '',
		answer: '',
	};
}

/**
 * Ensure every item has a stable UUID without rewriting existing valid ids.
 *
 * @param {Array<Object>} items Raw items.
 * @return {Array<{id:string,question:string,answer:string}>} Normalized items.
 */
export function ensureStableIds(items) {
	const list = Array.isArray(items) ? items : [];
	const seen = new Set();
	return list.map((item) => {
		const question =
			item && typeof item.question === 'string' ? item.question : '';
		const answer = item && typeof item.answer === 'string' ? item.answer : '';
		let id = item && typeof item.id === 'string' ? item.id.trim().toLowerCase() : '';
		if (!isValidUuid(id) || seen.has(id)) {
			id = createItemId();
		}
		seen.add(id);
		return { id, question, answer };
	});
}

/**
 * @param {Array<Object>} items Current items.
 * @return {Array<Object>} Items with one empty row appended.
 */
export function insertItem(items) {
	return [...ensureStableIds(items), createEmptyItem()];
}

/**
 * @param {Array<Object>} items Current items.
 * @param {number}        index Index to update.
 * @param {Object}        patch Partial fields.
 * @return {Array<Object>} Next items.
 */
export function updateItemAt(items, index, patch) {
	const list = ensureStableIds(items);
	if (index < 0 || index >= list.length) {
		return list;
	}
	const next = { ...list[index] };
	if (Object.prototype.hasOwnProperty.call(patch, 'question')) {
		next.question = String(patch.question ?? '');
	}
	if (Object.prototype.hasOwnProperty.call(patch, 'answer')) {
		next.answer = String(patch.answer ?? '');
	}
	// Never allow client code to wipe a stable id via patch.
	if (
		Object.prototype.hasOwnProperty.call(patch, 'id') &&
		isValidUuid(String(patch.id || ''))
	) {
		next.id = String(patch.id).trim().toLowerCase();
	}
	return list.map((item, i) => (i === index ? next : item));
}

/**
 * @param {Array<Object>} items Current items.
 * @param {number}        index Index to remove.
 * @return {Array<Object>} Next items.
 */
export function removeItemAt(items, index) {
	const list = ensureStableIds(items);
	if (index < 0 || index >= list.length) {
		return list;
	}
	return list.filter((_, i) => i !== index);
}

/**
 * Move an item from one index to another.
 *
 * @param {Array<Object>} items    Current items.
 * @param {number}        fromIndex Source index.
 * @param {number}        toIndex   Destination index.
 * @return {Array<Object>} Reordered items (ids preserved).
 */
export function reorderItems(items, fromIndex, toIndex) {
	const list = ensureStableIds(items);
	if (
		fromIndex < 0 ||
		toIndex < 0 ||
		fromIndex >= list.length ||
		toIndex >= list.length ||
		fromIndex === toIndex
	) {
		return list;
	}
	const next = [...list];
	const [moved] = next.splice(fromIndex, 1);
	next.splice(toIndex, 0, moved);
	return next;
}

/**
 * Strip empty rows for saved visible markup / future schema emission.
 * Empty rows may still be kept in editor attributes.
 *
 * @param {Array<Object>} items Items.
 * @return {Array<Object>} Rows with a question or non-empty plain answer.
 */
export function getVisibleItems(items) {
	return ensureStableIds(items).filter((item) => {
		const question = (item.question || '').trim();
		const plain = String(item.answer || '')
			.replace(/<[^>]+>/g, ' ')
			.replace(/\s+/g, ' ')
			.trim();
		return question !== '' || plain !== '';
	});
}

/**
 * Complete Q/A pairs (both sides filled).
 *
 * @param {Array<Object>} items Items.
 * @return {Array<Object>} Complete pairs.
 */
export function getCompleteItems(items) {
	return ensureStableIds(items).filter((item) => {
		const question = (item.question || '').trim();
		const plain = String(item.answer || '')
			.replace(/<[^>]+>/g, ' ')
			.replace(/\s+/g, ' ')
			.trim();
		return question !== '' && plain !== '';
	});
}
