/**
 * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

import $ from 'jquery';
import throttle from 'lodash/throttle';

export function trackArticlePosition() {
	let headingsData = [];
	const toc = $( '.secondary-navigation' );
	const tocLinks = $( '.secondary-navigation a' );
	const currentItemClass = 'secondary-navigation__current-position';
	let tocItemClicked = false;

	function getHeadingsData() {
		headingsData = [];

		$( ':header' ).each( function() {
			const currentHeading = $( this );
			const currentHeadingId = currentHeading.attr( 'id' );

			if ( !currentHeadingId ) {
				return true;
			}

			headingsData.unshift( {
				top: currentHeading.offset().top,
				tocItem: toc.find( `a[href$="#${ currentHeadingId }"]` )
			} );
		} );
	}

	function updateToc() {
		// Prevent updating when ToC item was clicked and page scrolled.
		if ( tocItemClicked ) {
			return;
		}

		// When ToC is not fixed to the right, there is no need for marking current position.
		if ( toc.css( 'position' ) !== 'fixed' ) {
			if ( tocLinks.hasClass( currentItemClass ) ) {
				tocLinks.removeClass( currentItemClass );
			}

			return;
		}

		const scrollTop = $( window ).scrollTop();
		const offsetAboveHeading = $( window ).height() / 3;

		for ( const hd of headingsData ) {
			if ( scrollTop > hd.top - offsetAboveHeading ) {
				if ( !hd.tocItem.hasClass( currentItemClass ) ) {
					tocLinks.removeClass( currentItemClass );
					hd.tocItem.addClass( currentItemClass );
				}

				return;
			}
		}

		if ( tocLinks.hasClass( currentItemClass ) ) {
			tocLinks.removeClass( currentItemClass );
		}
	}

	tocLinks.click( function() {
		tocItemClicked = true;

		if ( tocLinks.hasClass( currentItemClass ) ) {
			tocLinks.removeClass( currentItemClass );
		}

		$( this ).addClass( currentItemClass );
		setTimeout( () => {
			tocItemClicked = false;
		}, 200 );
	} );

	$( window ).resize( () => {
		getHeadingsData();
		updateToc();
	} );

	$( window ).scroll( throttle( updateToc, 100 ) );

	// Timeout because highlight.js takes time to run and it changes headings position.
	setTimeout( function() {
		getHeadingsData();
		updateToc();
	}, 200 );
}
