import { PropTypes, React } from '@gravityforms/libraries';
import Button from '../../../elements/Button';
import Pill from '../../../elements/Pill';
import Text from '../../../elements/Text';
import { DATE_KEY, SEARCH_KEY, getModules } from '../utils';

const { forwardRef } = React;

/**
 * @module ActiveFilters
 * @description The ActiveFilters module.
 *
 * @since 5.1.0
 *
 * @param {object}      props                   The component props.
 * @param {boolean}     props.isLoading         Whether the data grid is loading.
 * @param {Array}       props.modules           The list of modules.
 * @param {object}      props.moduleAttributes  The module attributes.
 * @param {object}      props.moduleState       The module state.
 * @param {Function}    props.setIsLoading      Set the loading state of the data grid.
 * @param {Function}    props.updateModuleState Update the module state.
 * @param {object|null} ref                     Ref to the component.
 *
 * @return {JSX.Element} The ActiveFilters component.
 */
const ActiveFilters = forwardRef( ( {
	isLoading = false,
	modules = [],
	moduleAttributes = {},
	moduleState = {},
	setIsLoading = () => {},
	updateModuleState = () => {},
}, ref ) => {
	const { filters = [] } = moduleState;
	const {
		pill: pillAttributes = {},
		reset: {
			onClick = () => {},
			...restResetAttributes
		} = {},
		i18n: {
			activeFiltersLabel: activeFiltersLabelI18n = '',
		} = {},
		onFilterChange = () => {},
	} = moduleAttributes?.activeFilters || {};

	if ( ! filters.length ) {
		return null;
	}

	const resetButtonProps = {
		onClick: ( event ) => {
			if ( isLoading ) {
				return;
			}

			const { BulkActions, DateFilters, GridPagination, Search } = getModules( modules, [ 'BulkActions', 'DateFilters', 'GridPagination', 'Search' ] );
			const updatedState = {
				filters: [],
				...( ( DateFilters && DateFilters?.getDefaultState() ) || {} ),
				...( ( Search && Search?.getDefaultState() ) || {} ),
				...( ( BulkActions && BulkActions?.getDefaultState() ) || {} ),
				...( ( GridPagination && GridPagination?.getDefaultState() ) || {} ),
			};
			const combinedState = { ...moduleState, ...updatedState };

			onClick( event );
			setIsLoading( true );

			onFilterChange( combinedState )
				.then( () => {
					updateModuleState( updatedState );
					setIsLoading( false );
				} )
				.catch( ( error ) => {
					// handle error.
					setIsLoading( false );
					console.info( error );
				} );
		},
		size: 'size-height-s',
		type: 'white',
		...restResetAttributes,
	};

	return (
		<div className="gform-data-grid__active-filters" ref={ ref }>
			<Text
				className="gform-data-grid__active-filters-label"
				color="comet"
				size="text-sm"
				weight="medium"
			>
				{ activeFiltersLabelI18n }
			</Text>
			{ filters.map( ( filter ) => (
				<Pill
					key={ filter.id }
					{ ...pillAttributes }
					content={ filter.label }
					onClick={ ( event ) => {
						if ( isLoading ) {
							return;
						}

						const { onClick: pillOnClick = () => {} } = pillAttributes;
						const updatedFilters = filters.filter( ( f ) => f.id !== filter.id );
						const { BulkActions, DateFilters, GridPagination, Search } = getModules( modules, [ 'BulkActions', 'DateFilters', 'GridPagination', 'Search' ] );
						const updatedState = {
							filters: updatedFilters,
							...( ( filter.key === DATE_KEY && DateFilters && DateFilters?.getDefaultState() ) || {} ),
							...( ( filter.key === SEARCH_KEY && Search && Search?.getDefaultState() ) || {} ),
							...( ( BulkActions && BulkActions?.getDefaultState() ) || {} ),
							...( ( GridPagination && GridPagination?.getDefaultState() ) || {} ),
						};
						const combinedState = { ...moduleState, ...updatedState };

						pillOnClick( event );
						setIsLoading( true );
						onFilterChange( combinedState )
							.then( () => {
								updateModuleState( updatedState );
								setIsLoading( false );
							} )
							.catch( ( error ) => {
								// handle error.
								setIsLoading( false );
								console.info( error );
							} );
					} }
				/>
			) ) }
			<Button { ...resetButtonProps } />
		</div>
	);
} );

ActiveFilters.propTypes = {
	isLoading: PropTypes.bool,
	modules: PropTypes.array,
	moduleAttributes: PropTypes.object,
	moduleState: PropTypes.object,
	setIsLoading: PropTypes.func,
	updateModuleState: PropTypes.func,
};

ActiveFilters.displayName = 'ActiveFilters';

export default {
	name: 'ActiveFilters',
	ActiveFilters,
};
