const Suggestion = ( { acceptSuggestion, formValues, formActions, layout, suggestions, countriesData } ) => {
	return (
		<div className="suggestion-container">
			<RadioButton
				checked={ ! acceptSuggestion }
				onChange={ () => formActions.setFormProperty( 'acceptSuggestion', false ) } >
				<span className="suggestion-title" dangerouslySetInnerHTML={ sanitizeHTML( layout.suggestion_original_title ) } />
				<Summary
					formValues={ formValues }
					layoutItems={ layout.items }
					summaryTemplate={ layout.summary }
					countriesData={ countriesData } />
				<Button compact
					onClick={ formActions.backFromSuggestion }
					className="suggestion-edit-button">
					{ __( 'Edit' ) }
				</Button>
			</RadioButton>
			<RadioButton
				checked={ acceptSuggestion }
				onChange={ () => formActions.setFormProperty( 'acceptSuggestion', true ) } >
				<span className="suggestion-title" dangerouslySetInnerHTML={ sanitizeHTML( layout.suggestion_corrected_title ) } />
				<Summary
					formValues={ formValues }
					layoutItems={ layout.items }
					summaryTemplate={ layout.summary }
					overrideFields={ suggestions }
					countriesData={ countriesData } />
			</RadioButton>
		</div>
	);
};
const renderSubTitle = ( subtitle ) => {
	if ( ! subtitle ) {
		return null;
	}

	return (
		<span className="indicators__subtitle" dangerouslySetInnerHTML={ sanitizeHTML( subtitle ) } />
	);
};
const renderLastUpdated = ( lastUpdated ) => {
	if ( ! lastUpdated ) {
		return null;
	}

	return (
		<div className="form-setting-explanation indicator__last-updated">
			<span dangerouslySetInnerHTML={ sanitizeHTML( lastUpdated ) } />
		</div>
	);
};
const ShippingServiceGroups = ( {
	schema,
	services,
	settings,
	currencySymbol,
	updateValue,
	settingsKey,
	errors,
	generalError,
} ) => {
	// Some shippers have so many services that it is helpful to organize them
	// into groups.  This code iterates over the services and extracts the group(s)
	// it finds.  When rendering, we can then iterate over the group(s).
	const servicesWithSettings = services.map( svc => Object.assign( {}, svc, settings[ svc.id ] ) );
	const serviceGroups = groupBy( servicesWithSettings, svc => svc.group );

	const renderServiceGroup = ( serviceGroup ) => {
		const groupFields = map( serviceGroups[ serviceGroup ], 'id' );
		const groupErrors = {};
		groupFields.forEach( ( fieldName ) => {
			if ( errors[ fieldName ] ) {
				groupErrors[ fieldName ] = errors[ fieldName ];
			}
		} );

		return (
			<ShippingServiceGroup
				key={ serviceGroup }
				title={ serviceGroups[ serviceGroup ][ 0 ].group_name }
				services={ serviceGroups[ serviceGroup ] }
				currencySymbol={ currencySymbol }
				updateValue={ updateValue }
				settingsKey={ settingsKey }
				errors={ groupErrors }
			/>
		);
	};

	return (
		<div className="wcc-shipping-services-groups">
			<FormLegend dangerouslySetInnerHTML={ sanitizeHTML( schema.title ) } />
			<FieldDescription text={ schema.description } />
			<div className={ classNames( 'wcc-shipping-services-groups-inner', { 'is-error': generalError } ) }>
				{ Object.keys( serviceGroups ).sort().map( renderServiceGroup ) }
			</div>
			{ generalError ? <FieldError text={ generalError } /> : null }
		</div>
	);
};
const Indicators = ( { schema, indicators } ) => {
	return (
		<FormFieldset>
			<FormLegend>
				<span dangerouslySetInnerHTML={ sanitizeHTML( schema.title ) } />
				{ renderSubTitle( schema.subtitle ) }
			</FormLegend>
			{ indicators.map( indicator => (
				<Indicator
					key={ indicator.id }
					icon={ indicator.icon }
					className={ indicator.class }
					message={ indicator.message }
					lastUpdated={ indicator.last_updated }
				/>
			) ) }
		</FormFieldset>
	);
};
const TextArea = ( { id, schema, value, placeholder, layout, updateValue, error } ) => {
	const handleChangeEvent = event => updateValue( event.target.value );
	const readOnly = 'undefined' === typeof layout.readonly ? false : layout.readonly;

	return (
		<FormFieldset>
			<FormLabel htmlFor={ id } dangerouslySetInnerHTML={ sanitizeHTML( schema.title ) } />
			<FormTextarea
				id={ id }
				name={ id }
				placeholder={ placeholder }
				readOnly={ readOnly }
				value={ value }
				onChange={ handleChangeEvent }
				isError={ error }
			/>
			{ error ? <FieldError text={ error } /> : <FieldDescription text={ schema.description } /> }
		</FormFieldset>
	);
};