/**
 * Creates an instance of the link title change listener.
 *
 * While the user dwells on a link, then it becomes the active link. The
 * change listener will remove a link's `title` attribute while it's the
 * active link.
 *
 * @return {ext.popups.ChangeListener}
 */
export default function linkTitle() {
	let savedTitle;

	/**
	 * Destroys the title attribute of the element, storing its value in local
	 * state so that it can be restored later (see `restoreTitleAttr`).
	 *
	 * @param {HTMLElement|undefined} el
	 */
	function destroyTitleAttr( el ) {
		// Has the user dwelled on a link? If we've already removed its title attribute, then NOOP.
		if ( el && !savedTitle ) {
			savedTitle = el.getAttribute( 'title' );
			el.setAttribute( 'title', '' );
		}
	}

	/**
	 * Restores the title attribute of the element.
	 *
	 * @param {HTMLElement|undefined} el
	 */
	function restoreTitleAttr( el ) {
		// Avoid overwriting a non-empty title with an empty one, just to be sure
		if ( el && savedTitle ) {
			el.setAttribute( 'title', savedTitle );
			savedTitle = undefined;
		}
	}

	return ( oldState, newState ) => {
		const oldLink = oldState && oldState.preview.activeLink;

		// Usually only one side is set when the user enters or leaves a link. Both sides contain
		// two different links when the user dwelled on a link immediately after abandoning another
		// (remembering that the ABANDON_END action is delayed by ~100 ms).
		if ( oldLink !== newState.preview.activeLink ) {
			restoreTitleAttr( oldLink );

			// FIXME: This will not work on anything other than 'reference' or 'preview' types as
			// mw.popups.register does not register the previewType as a key in
			// newState.preview.enabled
			// This is not a problem at time of writing (November 2022) but will become a problem if
			// we introduce custom preview types that must remove the title attribute.
			if ( newState.preview.enabled[ newState.preview.previewType ] ) {
				destroyTitleAttr( newState.preview.activeLink );
			}
		}
	};
}
