text: /**
   * External dependencies
   */
  import { __, _n, sprintf } from '@wordpress/i18n';
  import {
  	InspectorControls,
  } from '@wordpress/editor';
  import {
  	Button,
  	PanelBody,
  	Placeholder,
  	ToggleControl,
  	withSpokenMessages,
  } from '@wordpress/components';
  import { SearchListItem } from '@woocommerce/components';
  import { Fragment } from '@wordpress/element';
  import PropTypes from 'prop-types';
  
  /**
   * Internal dependencies
   */
  import ProductCategoryControl from '../../../components/product-category-control';
  import { IconReviewsByCategory } from '../../../components/icons';
  import EditorContainerBlock from '../editor-container-block.js';
  import NoReviewsPlaceholder from './no-reviews-placeholder.js';
  import { getBlockControls, getSharedReviewContentControls, getSharedReviewListControls } from '../edit-utils.js';
  
  /**
   * Component to handle edit mode of "Reviews by Category".
   */
  const ReviewsByCategoryEditor = ( { attributes, debouncedSpeak, setAttributes } ) => {
  	const { editMode, categoryIds } = attributes;
  
  	const renderCategoryControlItem = ( args ) => {
  		const { item, search, depth = 0 } = args;
  		const classes = [
  			'woocommerce-product-categories__item',
  		];
  		if ( search.length ) {
  			classes.push( 'is-searching' );
  		}
  		if ( depth === 0 && item.parent !== 0 ) {
  			classes.push( 'is-skip-level' );
  		}
  
  		const accessibleName = ! item.breadcrumbs.length ?
  			item.name :
  			`${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`;
  
  		return (
  			<SearchListItem
  				className={ classes.join( ' ' ) }
  				{ ...args }
  				showCount
  				aria-label={ sprintf(
  					_n(
  						'%s, has %d product',
  						'%s, has %d products',
  						item.count,
  						'woocommerce'
  					),
  					accessibleName,
  					item.count
  				) }
  			/>
  		);
  	};
  
  	const getInspectorControls = () => {
  		return (
  			<InspectorControls key="inspector">
  				<PanelBody
  					title={ __( 'Category', 'woocommerce' ) }
  					initialOpen={ false }
  				>
  					<ProductCategoryControl
  						selected={ attributes.categoryIds }
  						onChange={ ( value = [] ) => {
  							const ids = value.map( ( { id } ) => id );
  							setAttributes( { categoryIds: ids } );
  						} }
  						renderItem={ renderCategoryControlItem }
  					/>
  				</PanelBody>
  				<PanelBody title={ __( 'Content', 'woocommerce' ) }>
  					<ToggleControl
  						label={ __( 'Product name', 'woocommerce' ) }
  						checked={ attributes.showProductName }
  						onChange={ () => setAttributes( { showProductName: ! attributes.showProductName } ) }
  					/>
  					{ getSharedReviewContentControls( attributes, setAttributes ) }
  				</PanelBody>
  				<PanelBody title={ __( 'List Settings', 'woocommerce' ) }>
  					{ getSharedReviewListControls( attributes, setAttributes ) }
  				</PanelBody>
  			</InspectorControls>
  		);
  	};
  
  	const renderEditMode = () => {
  		const onDone = () => {
  			setAttributes( { editMode: false } );
  			debouncedSpeak(
  				__(
  					'Showing Reviews by Category block preview.',
  					'woocommerce'
  				)
  			);
  		};
  
  		return (
  			<Placeholder
  				icon={ <IconReviewsByCategory className="block-editor-block-icon" /> }
  				label={ __( 'Reviews by Category', 'woocommerce' ) }
  			>
  				{ __(
  					'Show product reviews from specific categories.',
  					'woocommerce'
  				) }
  				<div className="wc-block-reviews__selection">
  					<ProductCategoryControl
  						selected={ attributes.categoryIds }
  						onChange={ ( value = [] ) => {
  							const ids = value.map( ( { id } ) => id );
  							setAttributes( { categoryIds: ids } );
  						} }
  					/>
  					<Button isDefault onClick={ onDone }>
  						{ __( 'Done', 'woocommerce' ) }
  					</Button>
  				</div>
  			</Placeholder>
  		);
  	};
  
  	if ( ! categoryIds || editMode ) {
  		return renderEditMode();
  	}
  
  	return (
  		<Fragment>
  			{ getBlockControls( editMode, setAttributes ) }
  			{ getInspectorControls() }
  			<EditorContainerBlock
  				attributes={ attributes }
  				className="wc-block-reviews-by-category"
  				icon={ <IconReviewsByCategory className="block-editor-block-icon" /> }
  				name={ __( 'Reviews by Category', 'woocommerce' ) }
  				noReviewsPlaceholder={ NoReviewsPlaceholder }
  			/>
  		</Fragment>
  	);
  };
  
  ReviewsByCategoryEditor.propTypes = {
  	/**
  	 * The attributes for this block.
  	 */
  	attributes: PropTypes.object.isRequired,
  	/**
  	 * The register block name.
  	 */
  	name: PropTypes.string.isRequired,
  	/**
  	 * A callback to update attributes.
  	 */
  	setAttributes: PropTypes.func.isRequired,
  	// from withSpokenMessages
  	debouncedSpeak: PropTypes.func.isRequired,
  };
  
  export default withSpokenMessages( ReviewsByCategoryEditor );
  