import { React, PropTypes } from '@gravityforms/libraries';

const { memo, useCallback } = React;

/**
 * @module GridCell
 * @description Renders a grid cell based on passed field data from the server.
 *
 * @since 3.3.0
 *
 * @param {object}   props            Component props.
 * @param {object}   data             Cell data.
 * @param {Function} handleGridClicks Passed handler for grid clicks if the field type supports it.
 * @param {Function} setGridData      Passed handler for grid changes if the field type supports it.
 *
 * @return {JSX.Element} The Grid Cell component.
 */
const GridCell = memo( ( {
	data = {},
	handleGridClicks,
	setGridData,
} ) => {
	const handleChange = useCallback( ( value ) => {
		if ( data?.props?.name ) {
			setGridData( data.props.name, value );
		}
	}, [ data.props, setGridData ] );

	const handleClicks = useCallback( ( event ) => {
		handleGridClicks( data.props, event );
	}, [ data.props, handleGridClicks ] );

	const renderNestedFields = ( entries ) => {
		if ( ! entries ) {
			return null;
		}

		return entries.map( ( nestedData, index ) => (
			<GridCell key={ index } data={ nestedData } setGridData={ setGridData } handleGridClicks={ handleGridClicks } />
		) );
	};

	if ( ! data.component ) {
		return null;
	}

	const Component = data.component;
	const props = {
		...data.props,
	};
	if ( data.components ) {
		props.children = renderNestedFields( data.components );
	}
	if ( handleGridClicks ) {
		props.onClick = handleClicks;
	}
	if ( setGridData ) {
		props.onChange = handleChange;
	}

	return <Component { ...props } />;
} );

GridCell.propTypes = {
	data: PropTypes.object,
	handleGridClicks: PropTypes.func,
	setGridData: PropTypes.func,
};

export default GridCell;
