// 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,
	TextAreaContainer,
	TextContainer,
	ToggleContainer,
	UploadContainer,
} from '@divi/field-library';
import {
	type Module,
} from '@divi/types';

// Local dependencies.
import { MapsListingAttrs } from './types';
import {
	buildDefaultAttrsPatch,
	buildDefaultInnerContent,
	convertGroupedOptions,
	convertSimpleOptions,
	getBlockDefaultsFromSchema,
	getEffectiveAttrValue,
	isToggleEnabled,
} from '../../utils';

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

const markerIconColorApplyToOptions = convertSimpleOptions([
	{ value: 'apply-fill', label: __('Fill', 'jet-engine-divi-views') },
	{ value: 'apply-stroke_unset-fill', label: __('Stroke', 'jet-engine-divi-views') },
	{ value: 'apply-fill_apply-stroke', label: __('Both', 'jet-engine-divi-views') },
	{ value: 'keep', label: __('Keep SVG colors', 'jet-engine-divi-views') },
]);

const MAPS_LISTING_DEFAULTS_FALLBACK: Record<string, any> = {
	lisitng_id: '',
	address_field: '',
	add_lat_lng: false,
	lat_lng_address_field: '',
	map_height: 500,
	posts_num: 6,
	auto_center: true,
	custom_center: '',
	custom_zoom: 11,
	custom_style: '',
	zoom_control: 'auto',
	zoom_controls: true,
	fullscreen_control: true,
	street_view_controls: true,
	map_type_controls: true,
	centering_on_open: false,
	marker_type: 'icon',
	marker_icon: 0,
	marker_icon_url: '',
	marker_image_field: '',
	marker_image_size: 'full',
	marker_image_field_custom: '',
	marker_icon_color_apply_to: 'keep_jsm',
	marker_label_type: 'post_title',
	marker_label_field: '',
	marker_label_field_custom: '',
	marker_label_text: '',
	marker_label_format_cb: '',
	marker_label_custom: false,
	marker_label_custom_output: '%s',
	multiple_marker_types: false,
	multiple_markers: [],
	marker_clustering: true,
	is_custom_marker_cluster_images: false,
	marker_cluster_images: [],
	user_location_enabled: false,
	user_location_marker_icon_color: '',
	user_location_marker_icon_color_apply_to: 'keep',
	user_location_marker_type: 'text',
	user_location_marker_label_text: 'Your Location',
	user_location_marker_icon: 0,
	user_location_marker_icon_url: '',
	user_location_marker_image_size: '',
	popup_width: 320,
	popup_offset: 40,
	popup_pin: false,
	popup_preloader: false,
	popup_open_on: 'click',
	custom_query: false,
	custom_query_id: '',
	posts_query: [],
	meta_query_relation: 'AND',
	tax_query_relation: 'AND',
	hide_widget_if: '',
	_block_id: '',
	_element_id: '',
};

const MAPS_LISTING_SELECT_ATTRS = [
	'lisitng_id',
	'marker_type',
	'marker_image_size',
	'marker_icon_color_apply_to',
	'marker_label_type',
	'user_location_marker_icon_color_apply_to',
	'user_location_marker_type',
	'user_location_marker_image_size',
	'popup_open_on',
	'custom_query_id',
	'meta_query_relation',
	'tax_query_relation',
	'hide_widget_if',
];

const MAPS_LISTING_TOGGLE_ATTRS = [
	'add_lat_lng',
	'auto_center',
	'zoom_controls',
	'fullscreen_control',
	'street_view_controls',
	'map_type_controls',
	'centering_on_open',
	'marker_label_custom',
	'multiple_marker_types',
	'marker_clustering',
	'is_custom_marker_cluster_images',
	'user_location_enabled',
	'popup_pin',
	'popup_preloader',
	'custom_query',
];

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

	const markerTypes = window.JetEngineDiviViews?.mapsListingConfig?.markerTypes || [];
	const markerLabelTypes = window.JetEngineDiviViews?.mapsListingConfig?.markerLabelTypes || [];
	const providerId = window.JetEngineDiviViews?.mapsListingConfig?.providerId;
	const blockDefaults = getBlockDefaultsFromSchema( 'mapsListing', MAPS_LISTING_DEFAULTS_FALLBACK );

	const userLocationMarkerTypes = markerTypes.filter((item: any) => ['icon', 'text'].includes(item.value));

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

		const patch = buildDefaultAttrsPatch( {
			attrs,
			defaults: blockDefaults,
			toggleKeys: MAPS_LISTING_TOGGLE_ATTRS,
			selectKeys: MAPS_LISTING_SELECT_ATTRS,
		} );

		if ( Object.keys( patch ).length ) {
			setAttrs( patch );
		}
	}, [ attrs, blockDefaults, setAttrs ] );

	const getAttrValue = ( key: string ) => getEffectiveAttrValue( {
		attrs,
		key,
		defaults: blockDefaults,
		toggleKeys: MAPS_LISTING_TOGGLE_ATTRS,
		selectKeys: MAPS_LISTING_SELECT_ATTRS,
	} );

	const getToggleDefaultAttr = ( key: string ) => buildDefaultInnerContent( {
		key,
		value: blockDefaults[ key ],
		toggleKeys: MAPS_LISTING_TOGGLE_ATTRS,
		selectKeys: MAPS_LISTING_SELECT_ATTRS,
	} );

	const isLatLngEnabled = isToggleEnabled( getAttrValue( 'add_lat_lng' ) );
	const isAutoCenterEnabled = isToggleEnabled( getAttrValue( 'auto_center' ) );
	const isCenteringOnOpenEnabled = isToggleEnabled( getAttrValue( 'centering_on_open' ) );
	const markerType = getAttrValue( 'marker_type' );
	const markerLabelType = getAttrValue( 'marker_label_type' );
	const isMarkerLabelCustomEnabled = isToggleEnabled( getAttrValue( 'marker_label_custom' ) );
	const isMultipleMarkerTypesEnabled = isToggleEnabled( getAttrValue( 'multiple_marker_types' ) );
	const isMarkerClusteringEnabled = isToggleEnabled( getAttrValue( 'marker_clustering' ) );
	const isCustomMarkerClusterImagesEnabled = isToggleEnabled( getAttrValue( 'is_custom_marker_cluster_images' ) );
	const isUserLocationEnabled = isToggleEnabled( getAttrValue( 'user_location_enabled' ) );
	const userLocationMarkerType = getAttrValue( 'user_location_marker_type' );
	const isCustomQueryEnabled = isToggleEnabled( getAttrValue( 'custom_query' ) );

	return (
		<React.Fragment>
			<GroupContainer
				id="general"
				title={__('General', 'jet-engine-divi-views')}
			>
				<FieldContainer
					attrName="lisitng_id.innerContent"
					label={__('Listing', 'jet-engine-divi-views')}
					description={__('Select a base listing item', 'jet-engine-divi-views')}
				>
					<SelectContainer
						options={convertSimpleOptions(window.JetEngineDiviViews?.listingOptions || [])}
					/>
				</FieldContainer>

				<FieldContainer
					attrName="address_field.innerContent"
					label={__('Address Meta Field', 'jet-engine-divi-views')}
					description={__('Set meta field key to get address from. Combine fields with "+" if needed.', 'jet-engine-divi-views')}
				>
					<TextContainer />
				</FieldContainer>

				<FieldContainer
					attrName="add_lat_lng.innerContent"
					label={__('Use Lat Lng Address Meta Field', 'jet-engine-divi-views')}
					description={__('Use latitude/longitude pair from meta field.', 'jet-engine-divi-views')}
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'add_lat_lng' )} />
				</FieldContainer>

				{isLatLngEnabled && (
					<FieldContainer
						attrName="lat_lng_address_field.innerContent"
						label={__('Lat Lng Address Meta Field', 'jet-engine-divi-views')}
						description={__('Set key like _lat+_lng (latitude first).', 'jet-engine-divi-views')}
					>
						<TextContainer />
					</FieldContainer>
				)}

				<FieldContainer
					attrName="map_height.innerContent"
					label={__('Map Height', 'jet-engine-divi-views')}
					description=""
				>
					<TextContainer type="number" min={100} max={1000} />
				</FieldContainer>

				<FieldContainer
					attrName="posts_num.innerContent"
					label={__('Posts number', 'jet-engine-divi-views')}
					description=""
				>
					<TextContainer type="number" min={1} max={1000} />
				</FieldContainer>

				<FieldContainer
					attrName="auto_center.innerContent"
					label={__('Automatically detect map center', 'jet-engine-divi-views')}
					description=""
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'auto_center' )} />
				</FieldContainer>

				{! isAutoCenterEnabled && (
					<FieldContainer
						attrName="custom_center.innerContent"
						label={__('Map Center', 'jet-engine-divi-views')}
						description=""
					>
						<TextAreaContainer />
					</FieldContainer>
				)}

				{! isAutoCenterEnabled && (
					<FieldContainer
						attrName="custom_zoom.innerContent"
						label={__('Custom Zoom', 'jet-engine-divi-views')}
						description=""
					>
						<TextContainer type="number" min={1} max={20} />
					</FieldContainer>
				)}

				<FieldContainer
					attrName="max_zoom.innerContent"
					label={__('Max Zoom', 'jet-engine-divi-views')}
					description=""
				>
					<TextContainer type="number" min={1} max={20} />
				</FieldContainer>

				<FieldContainer
					attrName="min_zoom.innerContent"
					label={__('Min Zoom', 'jet-engine-divi-views')}
					description=""
				>
					<TextContainer type="number" min={1} max={10} />
				</FieldContainer>

				<FieldContainer
					attrName="centering_on_open.innerContent"
					label={__('Centering map on marker click', 'jet-engine-divi-views')}
					description=""
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'centering_on_open' )} />
				</FieldContainer>

				{isCenteringOnOpenEnabled && (
					<FieldContainer
						attrName="zoom_on_open.innerContent"
						label={__('Zoom Map', 'jet-engine-divi-views')}
						description=""
					>
						<TextContainer type="number" min={1} max={20} />
					</FieldContainer>
				)}
			</GroupContainer>

			<GroupContainer id="marker" title={__('Marker', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="marker_type.innerContent"
					label={__('Marker Type', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer options={convertSimpleOptions(markerTypes)} />
				</FieldContainer>

				{'icon' === markerType && (
					<FieldContainer
						attrName="marker_icon_url.innerContent"
						label={__('Image/Icon', 'jet-engine-divi-views')}
						description=""
					>
						<UploadContainer />
					</FieldContainer>
				)}

				{'dynamic_image' === markerType && (
					<FieldContainer
						attrName="marker_image_field.innerContent"
						label={__('Meta Field', 'jet-engine-divi-views')}
						description=""
					>
						<SelectContainer options={convertGroupedOptions(window.JetEngineDiviViews?.metaFields || [])} />
					</FieldContainer>
				)}

				{'dynamic_image' === markerType && (
					<FieldContainer
						attrName="marker_image_field_custom.innerContent"
						label={__('Or enter meta field key', 'jet-engine-divi-views')}
						description={__('This field overrides Meta Field value.', 'jet-engine-divi-views')}
					>
						<TextContainer />
					</FieldContainer>
				)}

				{'text' === markerType && (
					<FieldContainer
						attrName="marker_label_type.innerContent"
						label={__('Marker Label', 'jet-engine-divi-views')}
						description=""
					>
						<SelectContainer options={convertSimpleOptions(markerLabelTypes)} />
					</FieldContainer>
				)}

				{'text' === markerType &&
					'meta_field' === markerLabelType && (
						<FieldContainer
							attrName="marker_label_field.innerContent"
							label={__('Meta Field', 'jet-engine-divi-views')}
							description=""
						>
							<SelectContainer options={convertGroupedOptions(window.JetEngineDiviViews?.metaFields || [])} />
						</FieldContainer>
					)}

				{'text' === markerType &&
					'meta_field' === markerLabelType && (
						<FieldContainer
							attrName="marker_label_field_custom.innerContent"
							label={__('Or enter meta field key', 'jet-engine-divi-views')}
							description={__('This field overrides Meta Field value.', 'jet-engine-divi-views')}
						>
							<TextContainer />
						</FieldContainer>
					)}

				{'text' === markerType &&
					'static_text' === markerLabelType && (
						<FieldContainer
							attrName="marker_label_text.innerContent"
							label={__('Marker Label', 'jet-engine-divi-views')}
							description=""
						>
							<TextContainer />
						</FieldContainer>
					)}

				<FieldContainer
					attrName="marker_image_size.innerContent"
					label={__('Image Size', 'jet-engine-divi-views')}
					description={__('Applies to image-based markers.', 'jet-engine-divi-views')}
				>
					<SelectContainer options={convertSimpleOptions(window.JetEngineDiviViews?.imageSizes || [])} />
				</FieldContainer>

				<FieldContainer
					attrName="marker_icon_color_apply_to.innerContent"
					label={__('Icon color source', 'jet-engine-divi-views')}
					description={__('Set how icon colors are applied.', 'jet-engine-divi-views')}
				>
					<SelectContainer
						options={convertSimpleOptions([
							{ value: 'keep_jsm', label: __('JetStyleManager', 'jet-engine-divi-views') },
							{ value: 'keep', label: __('Original SVG colors', 'jet-engine-divi-views') },
						])}
					/>
				</FieldContainer>

				<FieldContainer
					attrName="marker_label_format_cb.innerContent"
					label={__('Callback', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer options={convertSimpleOptions(window.JetEngineDiviViews?.filterCallbacks || [])} />
				</FieldContainer>

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

				{isMarkerLabelCustomEnabled && (
					<FieldContainer
						attrName="marker_label_custom_output.innerContent"
						label={__('Label format', 'jet-engine-divi-views')}
						description={__('%s will be replaced with field value', 'jet-engine-divi-views')}
					>
						<TextAreaContainer />
					</FieldContainer>
				)}

				<FieldContainer
					attrName="multiple_marker_types.innerContent"
					label={__('Use different markers by conditions', 'jet-engine-divi-views')}
					description={__('Use default marker when conditions are not met.', 'jet-engine-divi-views')}
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'multiple_marker_types' )} />
				</FieldContainer>

				{isMultipleMarkerTypesEnabled && (
					<FieldContainer
						attrName="multiple_markers.innerContent"
						label={__('Conditional Markers (JSON)', 'jet-engine-divi-views')}
						description={__('Advanced: set an array of conditional marker objects.', 'jet-engine-divi-views')}
					>
						<TextAreaContainer />
					</FieldContainer>
				)}

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

				{isMarkerClusteringEnabled && (
					<>
						<FieldContainer
							attrName="cluster_max_zoom.innerContent"
							label={__('Cluster Max Zoom', 'jet-engine-divi-views')}
							description={__('Maximum zoom level for clustering.', 'jet-engine-divi-views')}
						>
							<TextContainer type="number" min={1} max={20} />
						</FieldContainer>
						<FieldContainer
							attrName="cluster_radius.innerContent"
							label={__('Cluster Radius', 'jet-engine-divi-views')}
							description={__('Cluster radius in px.', 'jet-engine-divi-views')}
						>
							<TextContainer type="number" min={10} max={400} />
						</FieldContainer>
					</>
				)}

				{['google', 'leaflet'].includes(providerId) && (
					<FieldContainer
						attrName="is_custom_marker_cluster_images.innerContent"
						label={__('Set Custom Marker Images', 'jet-engine-divi-views')}
						description=""
					>
						<ToggleContainer defaultAttr={getToggleDefaultAttr( 'is_custom_marker_cluster_images' )} />
					</FieldContainer>
				)}

				{['google', 'leaflet'].includes(providerId) &&
					isCustomMarkerClusterImagesEnabled && (
						<FieldContainer
							attrName="marker_cluster_images.innerContent"
							label={__('Cluster Marker Images (JSON)', 'jet-engine-divi-views')}
							description={__('Advanced: set an array with image URL and width.', 'jet-engine-divi-views')}
						>
							<TextAreaContainer />
						</FieldContainer>
					)}
			</GroupContainer>

			<GroupContainer id="user-location" title={__('User Location', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="user_location_enabled.innerContent"
					label={__('Enable User Location Marker', 'jet-engine-divi-views')}
					description=""
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'user_location_enabled' )} />
				</FieldContainer>

				{isUserLocationEnabled && (
					<FieldContainer
						attrName="user_location_marker_type.innerContent"
						label={__('Marker Type', 'jet-engine-divi-views')}
						description=""
					>
						<SelectContainer options={convertSimpleOptions(userLocationMarkerTypes)} />
					</FieldContainer>
				)}

				{isUserLocationEnabled &&
					'icon' === userLocationMarkerType && (
						<FieldContainer
							attrName="user_location_marker_icon_url.innerContent"
							label={__('Image/Icon', 'jet-engine-divi-views')}
							description=""
						>
							<UploadContainer />
						</FieldContainer>
					)}

				{isUserLocationEnabled &&
					'text' === userLocationMarkerType && (
						<FieldContainer
							attrName="user_location_marker_label_text.innerContent"
							label={__('Marker Label', 'jet-engine-divi-views')}
							description=""
						>
							<TextContainer />
						</FieldContainer>
					)}

				{isUserLocationEnabled &&
					'icon' === userLocationMarkerType && (
						<FieldContainer
							attrName="user_location_marker_image_size.innerContent"
							label={__('Image Size', 'jet-engine-divi-views')}
							description=""
						>
							<SelectContainer options={convertSimpleOptions(window.JetEngineDiviViews?.imageSizes || [])} />
						</FieldContainer>
					)}

				{isUserLocationEnabled &&
					'icon' === userLocationMarkerType && (
						<FieldContainer
							attrName="user_location_marker_icon_color_apply_to.innerContent"
							label={__('Icon color apply to', 'jet-engine-divi-views')}
							description=""
						>
							<SelectContainer options={markerIconColorApplyToOptions} />
						</FieldContainer>
					)}
			</GroupContainer>

			<GroupContainer id="popup" title={__('Popup', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="popup_width.innerContent"
					label={__('Marker Popup Width', 'jet-engine-divi-views')}
					description={__('Set popup width in pixels.', 'jet-engine-divi-views')}
				>
					<TextContainer type="number" min={150} max={600} />
				</FieldContainer>

				<FieldContainer
					attrName="popup_offset.innerContent"
					label={__('Vertical Offset', 'jet-engine-divi-views')}
					description={__('Set vertical popup offset in pixels.', 'jet-engine-divi-views')}
				>
					<TextContainer type="number" min={0} max={200} />
				</FieldContainer>

				<FieldContainer
					attrName="popup_preloader.innerContent"
					label={__('Add popup preloader', 'jet-engine-divi-views')}
					description={__('Show loading animation while popup data is fetching.', 'jet-engine-divi-views')}
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'popup_preloader' )} />
				</FieldContainer>

				<FieldContainer
					attrName="popup_open_on.innerContent"
					label={__('Open On', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer
						options={convertSimpleOptions([
							{ value: 'click', label: __('Click', 'jet-engine-divi-views') },
							{ value: 'hover', label: __('Hover', 'jet-engine-divi-views') },
						])}
					/>
				</FieldContainer>
			</GroupContainer>

			<GroupContainer id="custom-query" title={__('Custom Query', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="custom_query.innerContent"
					label={__('Use Custom Query', 'jet-engine-divi-views')}
					description=""
				>
					<ToggleContainer defaultAttr={getToggleDefaultAttr( 'custom_query' )} />
				</FieldContainer>

				{isCustomQueryEnabled && (
					<FieldContainer
						attrName="custom_query_id.innerContent"
						label={__('Custom Query', 'jet-engine-divi-views')}
						description=""
					>
						<SelectContainer options={convertSimpleOptions(window.JetEngineDiviViews?.queriesList || [])} />
					</FieldContainer>
				)}
			</GroupContainer>

			<GroupContainer id="posts-query" title={__('Posts Query', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="posts_query.innerContent"
					label={__('Posts Query (JSON)', 'jet-engine-divi-views')}
					description={__('Advanced: set query clauses as array.', 'jet-engine-divi-views')}
				>
					<TextAreaContainer />
				</FieldContainer>

				<FieldContainer
					attrName="meta_query_relation.innerContent"
					label={__('Meta query relation', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer
						options={convertSimpleOptions([
							{ value: 'AND', label: __('AND', 'jet-engine-divi-views') },
							{ value: 'OR', label: __('OR', 'jet-engine-divi-views') },
						])}
					/>
				</FieldContainer>

				<FieldContainer
					attrName="tax_query_relation.innerContent"
					label={__('Tax query relation', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer
						options={convertSimpleOptions([
							{ value: 'AND', label: __('AND', 'jet-engine-divi-views') },
							{ value: 'OR', label: __('OR', 'jet-engine-divi-views') },
						])}
					/>
				</FieldContainer>
			</GroupContainer>

			<GroupContainer id="visibility" title={__('Block Visibility', 'jet-engine-divi-views')}>
				<FieldContainer
					attrName="hide_widget_if.innerContent"
					label={__('Hide block if', 'jet-engine-divi-views')}
					description=""
				>
					<SelectContainer
						options={convertSimpleOptions(window.JetEngineDiviViews?.hideOptions || [])}
					/>
				</FieldContainer>
			</GroupContainer>

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