import {
	Button,
	Dashicon,
	PanelBody,
} from '@wordpress/components';
import {
	Fragment,
	useCallback,
	useEffect,
	useMemo,
	useState,
} from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { SelectControl, TextControl } from '../shared/wp-form-controls';

import './interaction-settings.css';

const eventOptions = [
	{ label: __( 'No', 'jeowp' ), value: 'none' },
	{ label: __( 'On click', 'jeowp' ), value: 'click' },
	{ label: __( 'On hover', 'jeowp' ), value: 'mouseover' },
];

export default function InteractionSettings( {
	interaction,
	interactionIndex,
	layer,
	onInsert,
	onUpdate,
	onDelete,
} ) {

	const fieldKeys = useMemo( () => {
		return Object.keys( layer.fields );
	}, [ layer.fields ] );

	const titleOptions = useMemo( () => {
		const newFieldKeys = fieldKeys.slice(1);
		return [
			{ label: fieldKeys[0], value: fieldKeys[0] },
			...newFieldKeys.map( ( field ) => {
				return { label: field, value: field };
			} ),
		];
	}, [ fieldKeys ] );

	const unusedFieldOptions = useMemo( () => {
		return fieldKeys.flatMap( ( key ) => {
			const found = interaction.fields.find( ( { field } ) => {
				return field === key;
			} );
			return found ? [] : [ { label: key, value: key } ];
		} );
	}, [ fieldKeys, interaction.fields ] );

	const [ newField, setNewField ] = useState( null );

	useEffect( () => {
		setNewField(
			unusedFieldOptions.length > 0 ? unusedFieldOptions[ 0 ].value : null
		);
	}, [ unusedFieldOptions ] );

	const changeEvent = useCallback(
		( on ) => {
			if ( interactionIndex !== -1 ) {
				if ( on === 'none' ) {
					onDelete( interaction.id );
				} else {
					onUpdate( interaction.id, { ...interaction, on } );
				}
			} else if ( on !== 'none' ) {
				onInsert( { ...interaction, on } );
			}
		},
		[ interaction, interactionIndex, onDelete, onInsert ]
	);

	const changeTitle = useCallback(
		( title ) => {
			onUpdate( interaction.id, { ...interaction, title } );
		},
		[ interaction, onUpdate ]
	);

	const addField = useCallback( () => {
		onUpdate( interaction.id, {
			...interaction,
			fields: [ ...interaction.fields, { field: newField, label: '' } ],
		} );
	}, [ interaction, newField, onUpdate ] );

	const updateLabel = ( key ) => ( label ) => {
		onUpdate( interaction.id, {
			...interaction,
			fields: interaction.fields.map( ( field ) => {
				return field.field === key ? { ...field, label } : field;
			} ),
		} );
	};

	const deleteField = ( key ) => () => {
		onUpdate( interaction.id, {
			...interaction,
			fields: interaction.fields.filter( ( field ) => {
				return field.field !== key;
			} ),
		} );
	};

	const interactive = interaction.on !== 'none';

	return (
		<PanelBody
			className="jeo-interaction-settings"
			title={ layer.id }
			initialOpen={ interactive }
		>
			<SelectControl
				label={ __( 'Show popup?', 'jeowp' ) }
				value={ interaction.on }
				options={ eventOptions }
				onChange={ changeEvent }
			/>
			{ interactive && (
				<Fragment>
					<div>
						<span>{ __( 'Title', 'jeowp' ) }</span>
						<span className="jeo-interaction-fields__field_required"> * </span>
						<SelectControl
							value={ interaction.title }
							options={ titleOptions }
							onChange={ changeTitle }
						/>
					</div>

					{ fieldKeys.length > 0 && (
						<fieldset className="jeo-interaction-fields">
							<legend>{ __( 'Fields', 'jeowp' ) }</legend>

							{ interaction.fields.length > 0 && (
								<div className="jeo-interaction-fields__grid">
									{ interaction.fields.map( ( { field, label } ) => {
										const inputId = `${ layer.id }_${ field }`;
										return (
											<Fragment key={ field }>
												<label htmlFor={ inputId }>{ field }</label>
												<TextControl
													id={ inputId }
													value={ label }
													placeholder={ layer.fields[ field ] }
													onChange={ updateLabel( field ) }
												/>
												<Button onClick={ deleteField( field ) }>
													<Dashicon icon="dismiss" />
												</Button>
											</Fragment>
										);
									} ) }
								</div>
							) }

							{ unusedFieldOptions.length > 0 && (
								<div className="jeo-interaction-add-field">
									<label htmlFor={ `${ layer.field }__add-field` }>
										{ __( 'Add field', 'jeowp' ) }
									</label>
									<SelectControl
										id={ `${ layer.field }__add-field` }
										value={ newField }
										options={ unusedFieldOptions }
										onChange={ setNewField }
									/>
									<Button variant="primary" onClick={ addField }>
										{ __( 'Add', 'jeowp' ) }
									</Button>
								</div>
							) }
						</fieldset>
					) }
				</Fragment>
			) }
		</PanelBody>
	);
}
