/**
 * External dependencies
 */
import classnames from 'classnames';
import { castArray } from 'lodash';

/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { Component } from '@wordpress/element';
import { IconButton, Dropdown, NavigableMenu } from '@wordpress/components';
import { withDispatch } from '@wordpress/data';

/**
 * Internal dependencies
 */
import './style.scss';
import BlockModeToggle from './block-mode-toggle';
import BlockRemoveButton from './block-remove-button';
import BlockDuplicateButton from './block-duplicate-button';
import BlockTransformations from './block-transformations';
import SharedBlockSettings from './shared-block-settings';
import UnknownConverter from './unknown-converter';

export class BlockSettingsMenu extends Component {
	constructor() {
		super( ...arguments );
		this.state = {
			isFocused: false,
		};
		this.onFocus = this.onFocus.bind( this );
		this.onBlur = this.onBlur.bind( this );
	}

	onFocus() {
		this.setState( {
			isFocused: true,
		} );
	}

	onBlur() {
		this.setState( {
			isFocused: false,
		} );
	}

	render() {
		const {
			uids,
			onSelect,
			focus,
			rootUID,
			renderBlockMenu = ( { children } ) => children,
			isHidden,
		} = this.props;
		const { isFocused } = this.state;
		const blockUIDs = castArray( uids );
		const count = blockUIDs.length;
		const firstBlockUID = blockUIDs[ 0 ];

		return (
			<div
				className={ classnames( 'editor-block-settings-menu', {
					'is-visible': isFocused || ! isHidden,
				} ) }
			>
				<Dropdown
					contentClassName="editor-block-settings-menu__popover"
					position="bottom left"
					renderToggle={ ( { onToggle, isOpen } ) => {
						const toggleClassname = classnames( 'editor-block-settings-menu__toggle', {
							'is-opened': isOpen,
						} );

						return (
							<IconButton
								className={ toggleClassname }
								onClick={ () => {
									if ( count === 1 ) {
										onSelect( firstBlockUID );
									}
									onToggle();
								} }
								icon="ellipsis"
								label={ __( 'More Options' ) }
								aria-expanded={ isOpen }
								focus={ focus }
								onFocus={ this.onFocus }
								onBlur={ this.onBlur }
							/>
						);
					} }
					renderContent={ ( { onClose } ) => (
						// Should this just use a DropdownMenu instead of a DropDown ?
						<NavigableMenu className="editor-block-settings-menu__content">
							{ renderBlockMenu( { onClose, children: [
								count === 1 && <BlockModeToggle key="mode-toggle" uid={ firstBlockUID } onToggle={ onClose } role="menuitem" />,
								count === 1 && <UnknownConverter key="unknown-converter" uid={ firstBlockUID } role="menuitem" />,
								<BlockDuplicateButton key="duplicate" uids={ uids } rootUID={ rootUID } role="menuitem" />,
								count === 1 && <SharedBlockSettings key="shared-block" uid={ firstBlockUID } onToggle={ onClose } itemsRole="menuitem" />,
								<BlockTransformations key="transformations" uids={ uids } onClick={ onClose } itemsRole="menuitem" />,
							] } ) }
						</NavigableMenu>
					) }
				/>
				<BlockRemoveButton
					uids={ uids }
					onFocus={ this.onFocus }
					onBlur={ this.onBlur }
				/>
			</div>
		);
	}
}

export default withDispatch( ( dispatch ) => ( {
	onSelect( uid ) {
		dispatch( 'core/editor' ).selectBlock( uid );
	},
} ) )( BlockSettingsMenu );
