import { makeRemotelyCallable, remoteFunction } from 'webextension-rpc';
import { parseMediaFragmentIdentifier } from '../util/media-fragment-identifier';

const retrieveBookmarks = remoteFunction('retrieveBookmarks');

function fragmentIdentifierToSelector(fragmentIdentifier) {
	if (fragmentIdentifier.startsWith('#')) {
		fragmentIdentifier = fragmentIdentifier.substring(1);
	}
	const selector = {
		type: 'FragmentSelector',
		value: fragmentIdentifier,
	};
	return selector;
}

function selectorToTime(selector) {
	if (selector.type !== 'FragmentSelector') {
		throw new Error(`Unsupported selector type: '${selector.type}'`);
	}
	const { start, end } = parseMediaFragmentIdentifier(selector.value);
	return { start, end };
}

export default async function init(playlist) {
	const eventEmitter = playlist.getEventEmitter();

	async function displayBookmarksInPage() {
		const bookmarks = await retrieveBookmarks({ url: document.URL });
		const bookmarksWithTime = bookmarks.map(bookmark => {
			const fragmentIdentifier = bookmark.url.split('#')[1];
			if (fragmentIdentifier === undefined) return null;

			const selector = fragmentIdentifierToSelector(fragmentIdentifier);
			try {
				const { start, end } = selectorToTime(selector);
				return { bookmark, start, end };
			} catch (err) {
				// Likely a fragment identifier we do not understand; skip it.
				return null;
			}
		}).filter(value => value !== null);

		bookmarksWithTime.sort(({ start: t1 }, { start: t2 }) => t1 - t2);

		const annotations = bookmarksWithTime.map(({ bookmark, start, end }) => ({
			start,
			end,
			id: bookmark.title,
			elementType: 'a',
			elementAttributes: {
				title: bookmark.title,
				href: bookmark.url,
				onclick: () => { eventEmitter.emit('select', start, end); },
			},
		}));

		playlist.setAnnotations({ annotations, annotationFormat: 'raw', editable: false });
		playlist.drawRequest();
	}

	makeRemotelyCallable({
		displayBookmarksInPage,
	});

	await displayBookmarksInPage();
}