import { React, PropTypes, classnames } from '@gravityforms/libraries';
import GridCell from './GridCell';
import GridLoader from './GridLoader';
import { getColumnStyle, getModules } from './utils';

const { forwardRef } = React;

/**
 * @module GridRow
 * @description A component used to display the grid row for the data grid.
 *
 * @since 4.3.0
 *
 * @param {object}      props                   The component props.
 * @param {Array}       props.columns           Array of column objects. Supply: component, key, props, sortable (optional), hideAt (optional). Key is used to match data keys for cells.
 * @param {object}      props.columnStyleProps  Style props for the column.
 * @param {object}      props.dataRowAttributes Custom attributes for the data row.
 * @param {Array}       props.dataRowClasses    Custom classes for the data row.
 * @param {string}      props.dataRowMinHeight  The minimum height for the data row.
 * @param {Function}    props.handleGridClicks  Passed handler for grid clicks if the field type supports it.
 * @param {string}      props.gridId            The ID of the data grid.
 * @param {boolean}     props.isLoading         Whether the data grid is loading.
 * @param {Array}       props.modules           The modules for the data grid.
 * @param {object}      props.moduleState       The module state.
 * @param {object}      props.row               The row data.
 * @param {number}      props.rowIndex          The index of the row.
 * @param {Function}    props.setGridData       Passed handler for field changes if the field type supports it.
 * @param {object|null} ref                     The ref object for this component.
 *
 * @return {JSX.Element} The GridRow component.
 */
const GridRow = forwardRef( ( props, ref ) => {
	const {
		columns = [],
		columnStyleProps = {},
		dataRowAttributes = {},
		dataRowClasses = [],
		dataRowMinHeight = '71px',
		handleGridClicks = () => {},
		gridId = '',
		isLoading = false,
		modules = [],
		moduleState = {},
		row = {},
		rowIndex = 0,
		setGridData = () => {},
	} = props;

	const rowId = row.id ? row.id : `${ gridId }-gform-data-grid__data-row-${ rowIndex }`;

	const { BulkActions } = getModules( modules, [ 'BulkActions' ] );

	const rowProps = {
		className: classnames( {
			'gform-data-grid__data-row': true,
			'gform-data-grid__data-row--selected': ( moduleState?.selectedRows || [] ).includes( rowId ),
		}, dataRowClasses ),
		id: `${ gridId }-${ row.id ?? rowIndex }`,
		style: {
			minHeight: dataRowMinHeight,
		},
		...dataRowAttributes,
	};
	return (
		<div { ...rowProps } ref={ ref }>
			{ BulkActions && <BulkActions.RowSelect rowId={ rowId } { ...props } /> }
			{ columns.map( ( column, columnIndex ) => {
				let content = null;
				const hasKey = column.key !== undefined;
				if ( ! hasKey || isLoading ) {
					content = <GridLoader animating={ hasKey } variableWidth={ column?.variableLoader || false } />;
				} else {
					content = <GridCell data={ row[ column.key ] } handleGridClicks={ handleGridClicks } setGridData={ setGridData } />;
				}
				return (
					<div
						key={ `${ gridId }-gform-data-grid__data-row-${ rowIndex }-column-${ columnIndex }` }
						className={ `gform-data-grid__column gform-data-grid__column-${ columnIndex }${ column.cellClasses ? ` ${ column.cellClasses }` : '' }` }
						style={ getColumnStyle( columnStyleProps[ column.key ] ) }
					>
						{ content }
					</div>
				);
			} ) }
		</div>
	);
} );

GridRow.propTypes = {
	columns: PropTypes.array,
	columnStyleProps: PropTypes.object,
	dataRowAttributes: PropTypes.object,
	dataRowClasses: PropTypes.array,
	dataRowMinHeight: PropTypes.string,
	handleGridClicks: PropTypes.func,
	gridId: PropTypes.string,
	isLoading: PropTypes.bool,
	modules: PropTypes.array,
	moduleState: PropTypes.object,
	row: PropTypes.object,
	rowIndex: PropTypes.number,
	setGridData: PropTypes.func,
};

GridRow.displayName = 'GridRow';

export default GridRow;
