// External dependencies.
import React, { ReactElement, useEffect } from 'react';

// WordPress dependencies.
import { __ } from '@wordpress/i18n';

// Divi dependencies.
import {
	AdminLabelGroup,
	FieldContainer,
} from '@divi/module';
import { GroupContainer } from '@divi/modal';
import {
	SelectContainer,
	TextContainer,
	ToggleContainer,
} from '@divi/field-library';
import { type Module } from '@divi/types';

// Local dependencies.
import { SearchAttrs } from './types';
import {
	buildDefaultAttrsPatch,
	buildDefaultInnerContent,
	convertObjectOptions,
	convertSimpleOptions,
	getBlockDefaultsFromSchema,
	getEffectiveAttrValue,
	isToggleEnabled as isToggleEnabledValue,
} from '../../utils';

declare global {
	interface Window {
		JSFDiviViews: any;
	}
}

const getAvailableFilters = () => {
	const filters = window.JSFDiviViews?.filters || {};
	return convertObjectOptions(filters['search'] || []);
};

const getAvailableProviders = () => {
	const providers = window.JSFDiviViews?.providers || {};
	return convertObjectOptions(providers);
};

const applyTypeOptions = convertSimpleOptions([
	{ value: 'ajax', label: __('AJAX', 'jet-engine-divi-views') },
	{ value: 'ajax-ontyping', label: __('AJAX on typing', 'jet-engine-divi-views') },
	{ value: 'mixed', label: __('AJAX + page reload', 'jet-engine-divi-views') },
	{ value: 'reload', label: __('Page reload', 'jet-engine-divi-views') },
]);

const SEARCH_DEFAULTS_FALLBACK: Record<string, any> = {
	filter_id: 0,
	content_provider: 'not-selected',
	apply_type: 'ajax',
	apply_button_text: __( 'Apply', 'jet-engine-divi-views' ),
	hide_apply_button: false,
	typing_min_letters_count: 3,
	show_label: false,
	query_id: '',
	additional_providers_enabled: false,
	additional_providers_list: [
		{
			additional_provider: '',
			additional_providers_list: '',
		},
	],
};

const SEARCH_SELECT_ATTRS = new Set( [
	'content_provider',
	'apply_type',
] );

const SEARCH_TOGGLE_ATTRS = new Set( [
	'hide_apply_button',
	'show_label',
	'additional_providers_enabled',
] );

export const SettingsContent = (props: Module.Settings.Panel.Props<SearchAttrs>): ReactElement => {
	const {
		defaultSettingsAttrs,
		attrs,
	} = props;
	const setAttrs = ( ( props as unknown as {
		setAttrs?: ( next: Partial<SearchAttrs> ) => void;
		setAttributes?: ( next: Partial<SearchAttrs> ) => void;
	} ).setAttrs || ( props as unknown as {
		onChange?: ( next: Partial<SearchAttrs> ) => void;
		setAttributes?: ( next: Partial<SearchAttrs> ) => void;
	} ).setAttributes || ( props as unknown as {
		onChange?: ( next: Partial<SearchAttrs> ) => void;
	} ).onChange );

	const searchDefaults = getBlockDefaultsFromSchema( 'search', SEARCH_DEFAULTS_FALLBACK );

	useEffect( () => {
		if ( ! setAttrs ) {
			return;
		}

		const next = buildDefaultAttrsPatch( {
			attrs,
			defaults: searchDefaults,
			toggleKeys: SEARCH_TOGGLE_ATTRS,
			selectKeys: SEARCH_SELECT_ATTRS,
		} );

		if ( Object.keys( next ).length ) {
			setAttrs( next );
		}
	}, [ attrs, setAttrs, searchDefaults ] );

	const getToggleDefaultAttr = ( key: string ) => buildDefaultInnerContent( {
		key,
		value: searchDefaults[ key ],
		toggleKeys: SEARCH_TOGGLE_ATTRS,
		selectKeys: SEARCH_SELECT_ATTRS,
	} );

	const getValue = ( key: string ) => getEffectiveAttrValue( {
		attrs,
		key,
		defaults: searchDefaults,
		toggleKeys: SEARCH_TOGGLE_ATTRS,
		selectKeys: SEARCH_SELECT_ATTRS,
	} );

	const applyType = getValue( 'apply_type' );
	const hideApplyButton = isToggleEnabledValue( getValue( 'hide_apply_button' ) );
	const isAjaxOnTyping = applyType === 'ajax-ontyping';

	return (
		<React.Fragment>
			<GroupContainer
				id="general"
				title={__('General', 'jet-engine-divi-views')}
			>
				<FieldContainer
					attrName="filter_id.innerContent"
					label={__('Select filter', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer options={getAvailableFilters()} />
				</FieldContainer>

				<FieldContainer
					attrName="content_provider.innerContent"
					label={__('This filter for', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer options={getAvailableProviders()} />
				</FieldContainer>

				<FieldContainer
					attrName="apply_type.innerContent"
					label={__('Apply type', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer options={applyTypeOptions} />
				</FieldContainer>

				{!isAjaxOnTyping && (
					<FieldContainer
					attrName="hide_apply_button.innerContent"
						label={__('Hide apply button', 'jet-engine-divi-views')}
						description=""
					>
						<ToggleContainer defaultAttr={ getToggleDefaultAttr( 'hide_apply_button' ) } />
					</FieldContainer>
				)}

				{!isAjaxOnTyping && !hideApplyButton && (
					<FieldContainer
						attrName="apply_button_text.innerContent"
						label={__('Apply button text', 'jet-engine-divi-views')}
						description=""
					>
						<TextContainer />
					</FieldContainer>
				)}

				{isAjaxOnTyping && (
					<FieldContainer
						attrName="typing_min_letters_count.innerContent"
						label={__('Typing min letters count', 'jet-engine-divi-views')}
						description=""
					>
						<TextContainer type="number" min={1} max={50} />
					</FieldContainer>
				)}

				<FieldContainer
					attrName="show_label.innerContent"
					label={__('Show filter label', 'jet-engine-divi-views')}
					description=""
				>
					<ToggleContainer defaultAttr={ getToggleDefaultAttr( 'show_label' ) } />
				</FieldContainer>

				<FieldContainer
					attrName="query_id.innerContent"
					label={__('Query ID', 'jet-engine-divi-views')}
					description={__(
						'Set unique query ID if you use multiple blocks of same provider on the page.',
						'jet-engine-divi-views'
					)}
				>
					<TextContainer />
				</FieldContainer>
			</GroupContainer>

			<AdminLabelGroup
				defaultGroupAttr={defaultSettingsAttrs?.module?.meta?.adminLabel}
			/>
		</React.Fragment>
	);
};
