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

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

const API_FILTER_LOCAL_STORAGE_KEY = 'ApiFilterState';

export class ApiFilter extends BaseComponent {
	/**
	 * Creates an aPI filter management component.
	 *
	 * @param element - The filter dropdown element.
	 */
	constructor( element ) {
		super( {
			apiFilterState: JSON.parse( localStorage.getItem( API_FILTER_LOCAL_STORAGE_KEY ) ) || {},
			activeFilters: Array.from( element.querySelectorAll( '.js-api-filter-checkbox input:checked' ) ).map( input => input.value ),
			filterItems: Array.from( document.querySelectorAll( '.js-api-filter-item' ) ).map( item => {
				return {
					element: item,
					tags: Object.keys( Object.assign( {}, item.dataset ) )
				};
			} ),
			filterTocItems: Array.from( document.querySelectorAll( '.js-api-toc-filter-item' ) ).map( item => {
				return {
					element: item,
					tags: Object.keys( Object.assign( {}, item.dataset ) )
				};
			} )
		} );

		this.elements = {
			filterDropdown: element,
			filterInputs: element.querySelectorAll( '.js-api-filter-checkbox input' ),
			filterLists: document.querySelectorAll( '.js-api-filter-list' ),
			tocFilterLists: document.querySelectorAll( '.js-api-toc-list' )
		};
	}

	/**
	 * Initializes navigation tree component on the page.
	 */
	static attach() {
		const filter = document.querySelector( '.js-api-filter' );

		if ( !filter ) {
			return;
		}

		new ApiFilter( filter ).init();
	}

	/**
	 * Initializes the navigation tree component with event listeners.
	 */
	init() {
		const { filterInputs } = this.elements;

		filterInputs.forEach( checkbox => {
			checkbox.addEventListener( 'change', () => {
				const isChecked = checkbox.checked;
				const filterType = checkbox.value;

				this.setState( {
					activeFilters: this.state.activeFilters.includes( filterType ) ?
						this.state.activeFilters.filter( el => el !== filterType ) :
						[ ...this.state.activeFilters, filterType ]
				} );

				this.saveApiFilterState( filterType, isChecked );
				this.filterItems();
				this.checkIfAllItemsAreHidden();
			} );
		} );

		this.setInitialApiFilterState();
		this.initialApplyApiFilterState();
		this.filterItems();
		this.checkIfAllItemsAreHidden();
		this.render();
	}

	render() {
		// No specific rendering logic for the navigation tree component.
	}

	/**
	 * Filters the items based on the active filters.
	 */
	filterItems() {
		const { filterItems, filterTocItems, activeFilters } = this.state;

		[ ...filterItems, ...filterTocItems ].forEach( item => {
			const hasActiveFilter = item.tags.some( tag => activeFilters.includes( tag ) );

			if ( hasActiveFilter ) {
				item.element.classList.remove( 'is-hidden' );
			} else {
				item.element.classList.add( 'is-hidden' );
			}
		} );
	}

	/**
	 * Checks if all items in the filter lists are hidden and updates the list state accordingly.
	 */
	checkIfAllItemsAreHidden() {
		const { filterLists, tocFilterLists } = this.elements;

		filterLists.forEach( list => {
			const isEmpty = list.querySelectorAll( '.js-api-filter-item:not(.is-hidden)' ).length === 0;

			if ( isEmpty ) {
				list.classList.add( 'is-empty' );
			} else {
				list.classList.remove( 'is-empty' );
			}
		} );

		tocFilterLists.forEach( list => {
			const isEmpty = list.querySelectorAll( '.js-api-toc-filter-item:not(.is-hidden)' ).length === 0;

			if ( isEmpty ) {
				list.classList.add( 'is-empty' );
			} else {
				list.classList.remove( 'is-empty' );
			}
		} );
	}

	/**
	 * Sets the initial state of the API filter into local storage when there is no set yet.
	 */
	setInitialApiFilterState() {
		const { apiFilterState } = this.state;
		const { filterDropdown } = this.elements;

		if ( Object.keys( apiFilterState ).length === 0 ) {
			Array.from( filterDropdown.querySelectorAll( '.js-api-filter-checkbox input' ) ).forEach( input => {
				const isChecked = input.checked;
				const filterType = input.value;

				this.saveApiFilterState( filterType, isChecked );
			} );
		}

		this.setState( {
			apiFilterState: JSON.parse( localStorage.getItem( API_FILTER_LOCAL_STORAGE_KEY ) ) || {},
			activeFilters: Object.keys( this.state.apiFilterState ).filter( key => this.state.apiFilterState[ key ] )
		} );
	}

	/**
	 * Applies the initial API filter state to the checkboxes in the filter dropdown.
	 */
	initialApplyApiFilterState() {
		const { apiFilterState } = this.state;
		const { filterDropdown } = this.elements;

		Array.from( filterDropdown.querySelectorAll( '.js-api-filter-checkbox input' ) ).forEach( input => {
			const isChecked = input.checked;
			const filterType = input.value;

			input.checked = apiFilterState[ filterType ] !== undefined ? apiFilterState[ filterType ] : isChecked;
		} );

		// this.dispatchInitialFolderStateDoneEvent();
	}

	/**
	 * Saves the state of the API filter checkbox in local storage.
	 *
	 * @param id - The ID of the filter checkbox.
	 * @param state - The state of the API filter (true for show, false for hide).
	 */
	saveApiFilterState( id, state ) {
		const { apiFilterState } = this.state;

		apiFilterState[ id ] = state;
		window.localStorage.setItem( API_FILTER_LOCAL_STORAGE_KEY, JSON.stringify( apiFilterState ) );
	}
}
