import htm from 'htm';
import { h } from 'preact';
import { useState, useCallback } from 'preact/hooks';

const html = htm.bind(h);

// configuration used to show behavior vs. workaround
let childFirst = true;
const Config = () => html`
	<label>
		<input
			type="checkbox"
			checked=${childFirst}
			onchange=${evt => {
				childFirst = evt.target.checked;
			}}
		/>
		Set child state before parent state.
	</label>
`;

const Child = ({ items, setItems }) => {
	let [pendingId, setPendingId] = useState(null);
	if (!pendingId) {
		setPendingId(
			(pendingId = Math.random()
				.toFixed(20)
				.slice(2))
		);
	}

	const onInput = useCallback(
		evt => {
			let val = evt.target.value,
				_items = [...items, { _id: pendingId, val }];
			if (childFirst) {
				setPendingId(null);
				setItems(_items);
			} else {
				setItems(_items);
				setPendingId(null);
			}
		},
		[childFirst, setPendingId, setItems, items, pendingId]
	);

	return html`
		<div class="item-editor">
			${items.map(
				(item, idx) => html`
					<input
						key=${item._id}
						value=${item.val}
						oninput=${evt => {
							let val = evt.target.value,
								_items = [...items];
							_items.splice(idx, 1, { ...item, val });
							setItems(_items);
						}}
					/>
				`
			)}

			<input
				key=${pendingId}
				placeholder="type to add an item"
				oninput=${onInput}
			/>
		</div>
	`;
};

const Parent = () => {
	let [items, setItems] = useState([]);
	return html`
		<div><${Config} /><${Child} items=${items} setItems=${setItems} /></div>
	`;
};

export default Parent;
