import { replaceBetween } from './utils';

export default ({ getState, item, setState }) => {
	let { text } = getState();
	const { selection } = getState();
	text = text || '';
	let newText;
	let newSelection;

	// Ignore multi-character selections.
	// NOTE: I was on the fence about whether more appropriate behavior would be
	// to add the list prefix (e.g. '-', '1.', '#', '##', '###') at the
	// beginning of the line where the selection begins, but for now I think
	// it's more natural to just ignore it in this case. If after using this
	// editor for a while it turns out the other way is more natural, that's
	// fine by me!
	if (selection.start !== selection.end) {
		return;
	}

	const spaceForPrefix = item.prefix.length + 1;
	const isNewLine = text.substring(selection.start - 1, selection.start) === '\n';
	if (isNewLine) { // We're at the start of a line
		newText = replaceBetween(text, selection, `${item.prefix} `);
		newSelection = { start: selection.start + spaceForPrefix, end: selection.start + spaceForPrefix };
	} else { // We're in the middle of a line
		// NOTE: It may be more natural for the prefix (e.g. '-', '1.', '#', '##')
		// to be prepended at the beginning of the line where the selection is,
		// rather than creating a new line (which is the behavior implemented here).
		// If the other way is more natural, that's fine by me!
		newText = replaceBetween(text, selection, `\n${item.prefix} `);
		newSelection = {
			start: selection.start + spaceForPrefix + 1,
			end: selection.start + spaceForPrefix + 1,
		};
	}

	setState({ text: newText }, () => {
		setTimeout(() => {
			setState({ selection: newSelection });
		}, 300);
	});
};