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

import { BaseComponent } from './base-component';

/**
 * Component responsible for handling breadcrumbs overflow and scroll behavior.
 */
export class Breadcrumbs extends BaseComponent {
	/**
	 * Creates a breadcrumbs component.
	 *
	 * @param element - The breadcrumbs DOM element
	 */
	constructor( element ) {
		super( {
			isOverflowing: false,
			hasLeftShadow: false
		} );

		this.elements = {
			container: element,
			wrapper: element.querySelector( '.c-breadcrumbs__wrapper' ),
			list: element.querySelector( '.c-breadcrumbs__list' )
		};

		// The threshold in pixels to determine when to show shadow
		this.threshold = 20;
	}

	/**
	 * Creates breadcrumbs component.
	 */
	static attach() {
		const breadcrumbsElement = document.querySelector( '.js-breadcrumbs' );

		if ( !breadcrumbsElement ) {
			return;
		}

		new Breadcrumbs( breadcrumbsElement ).init();
	}

	/**
	 * Initializes the breadcrumbs component.
	 */
	init() {
		window.addEventListener( 'resize', this.checkOverflow.bind( this ) );
		this.elements.wrapper.addEventListener( 'scroll', this.checkShadow.bind( this ) );

		this.checkOverflow();
		this.checkShadow();
	}

	/**
	 * Renders the breadcrumbs component.
	 * Checks if breadcrumbs are wider than their container and adds necessary styling.
	 */
	render( prevState, state = this.state ) {
		const { wrapper, list, container } = this.elements;

		if ( !!prevState.isOverflowing !== !!state.isOverflowing ) {
			if ( state.isOverflowing ) {
				const scroll = () => {
					wrapper.style.overflowX = 'auto';
					wrapper.scrollLeft = list.scrollWidth - wrapper.clientWidth + 10;
				};

				scroll();

				if ( document.readyState === 'loading' ) {
					window.addEventListener( 'load', scroll );
				}
			} else {
				// Reset styles if breadcrumbs fit in container
				wrapper.style.overflowX = 'visible';
			}
		}

		// Handle shadow class based on state change
		container.classList.toggle( 'c-breadcrumbs--shadow-left', state.hasLeftShadow );
	}

	/**
	 * Checks if the breadcrumbs overflow their container and updates state accordingly.
	 */
	checkOverflow() {
		const { wrapper, list } = this.elements;

		const wrapperWidth = wrapper.clientWidth;
		const listWidth = list.scrollWidth;

		// Update overflow state
		const isOverflowing = listWidth > wrapperWidth + this.threshold;

		if ( isOverflowing !== this.state.isOverflowing ) {
			this.setState( { isOverflowing } );
		}
	}

	/**
	 * Checks if shadow should be displayed and updates state accordingly.
	 */
	checkShadow() {
		const hasLeftShadow = this.elements.wrapper.scrollLeft > 0;

		if ( this.state.hasLeftShadow !== hasLeftShadow ) {
			this.setState( {
				hasLeftShadow
			} );
		}
	}
}
