/**
 * Form fields multi-select component to be used in the inspector controls
 */

/**
 * WordPress provides React during the page load. This is for TypeScript type checking only.
 *
 * Importing React from @wordpress/element causes "Cannot read property 'createElement' of undefined"
 */
import React from 'react';

import { withSelect } from '@wordpress/data';
import {
	ASMSelectControl,
	ASMSelectControlItem,
	ASMSelectControlProps,
} from '../../components/controls-inspector/sidebar/ASMSelectControl';
import { TextControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';

function FilterFieldOptions(props: {
	item: ASMSelectControlItem;
	meta: ASMSelectControlItem['meta'];
	setMeta: (meta: ASMSelectControlItem['meta']) => void;
}): JSX.Element {
	const { item, meta, setMeta } = props;

	return (
		<>
			<TextControl
				value={meta?.label}
				onChange={(value) => setMeta({ ...meta, label: value })}
				label={__('Custom Label', 'gp-entry-blocks')}
			/>
		</>
	);
}

interface FilterFieldsControlProps extends BlockProps<any> {
	label: string;
}

function FilterFieldsControl(
	props: FilterFieldsControlProps & {
		formFields: {
			id: string;
			label: string;
			displayOnly: boolean;
			[key: string]: any;
		}[];
	}
) {
	function onChange(val) {
		props.setAttributes({ filters: val });
	}

	const formInputs = [];

	for (const formField of props.formFields) {
		if (formField.displayOnly) {
			continue;
		}

		const { filterBlockUnsupportedInputTypes: unsupportedInputTypes } =
			window.GPEB;
		const inputType = formField?.inputType || formField.type;

		if (unsupportedInputTypes.indexOf(inputType) !== -1) {
			continue;
		}

		formInputs.push({
			type: 'field',
			allowMultiple: 'fieldId',
			meta: {
				fieldId: formField.id,
			},
			label: formField.label,
			group: __('Fields', 'gp-entry-blocks'),
			allowSorting: true,
		});

		if (formField.inputs) {
			for (const input of formField.inputs) {
				formInputs.push({
					type: 'field',
					allowMultiple: 'fieldId',
					meta: {
						fieldId: input.id,
						sortingId: input.id,
					},
					label: formField.label + ' (' + input.label + ')',
					optionLabel: '\xa0\xa0\xa0\xa0' + input.label,
					group: __('Fields', 'gp-entry-blocks'),
					allowSorting: true,
				});
			}
		}
	}

	const items: ASMSelectControlProps['items'] = [
		{
			type: 'all',
			label: __('Search All', 'gp-entry-blocks'),
		},
		...formInputs,
		{
			type: 'date_created',
			label: __('Date Created', 'gp-entry-blocks'),
			group: __('Meta', 'gp-entry-blocks'),
			allowSorting: true,
		},
		{
			type: 'created_by',
			label: __('Created By', 'gp-entry-blocks'),
			group: __('Meta', 'gp-entry-blocks'),
			allowSorting: true,
		},
		{
			type: 'entry_id',
			label: __('Entry ID', 'gp-entry-blocks'),
			group: __('Meta', 'gp-entry-blocks'),
			allowSorting: true,
		},
	].filter(Boolean);

	return (
		<ASMSelectControl
			onChange={onChange}
			items={items}
			placeholder={__('Select a Filter Field', 'gp-entry-blocks')}
			value={props.attributes.filters ?? []}
			label={props.label}
			id="gpeb-filter-selector"
			itemOptions={FilterFieldOptions}
			itemOptionsModalTitle={__(
				'Filter Field Options',
				'gp-entry-blocks'
			)}
		/>
	);
}

// @ts-ignore
export default withSelect((select, ownProps) => {
	return {
		formFields: select('gp-entry-blocks').getFormFields(
			ownProps.context['gp-entry-blocks/formId']
		),
	};
})(FilterFieldsControl);
