/**
 * WordPress Dependencies
 */
import { __ } from "@wordpress/i18n";
import { BlockControls } from "@wordpress/block-editor";
import {
	ToolbarGroup,
	ToolbarItem,
	DropdownMenu,
	SelectControl,
	Button,
	Popover,
	Spinner,
	__experimentalHStack as HStack,
	__experimentalVStack as VStack,
} from '@wordpress/components';
import { useEntityRecord } from '@wordpress/core-data';
import { useState } from '@wordpress/element';
import {
	registerFormatType,
	applyFormat,
	removeFormat,
	useAnchor,
	toggleFormat,
} from "@wordpress/rich-text";

/**
 * Internal dependencies
 */
import {
	firstNameIcon,
	lastNameIcon,
	countryIcon,
	emailIcon,
	userRoleIcon,
	userIdIcon,
	profileDataIcon,
	customFieldIcon,
} from "./../admin-icons";

const PWP_TYPE = "pwp-pro/visitor-data";

// Dropdown of all VisitorData options
const VisitorDataMenu = ( { value, onChange, activeAttributes, isActive, contentRef } ) => {

	// Checking if there's a selected attribute.
	const visitorData = activeAttributes?.data ?? undefined;

	// Handle custom fields UI popover.
	const [ isPopoverVisible, setIsPopoverVisible ] = useState( false );
	const togglePopover = () => {
		setIsPopoverVisible( ( state ) => ! state );
	};

	// Wrapper to update the <pwp-user-data> element and its' data attribute.
	const toggleData = ( newData ) => {
		// Check for valid data.
		if ( ! newData || '' === newData.trim() ) {
			// Remove rich format if nothing to set.
			onChange( removeFormat( value, PWP_TYPE ) );
		} else if ( visitorData === newData ) {
			// Remove if re-selecting the same value.
			onChange( removeFormat( value, PWP_TYPE ) );
		} else {
			onChange(
				// use apply to allow switching data used.
				applyFormat( value, {
					type: PWP_TYPE,
					attributes: {
						data: newData
					},
				} )
			);
		}
	};

	// variable holder of all options to display.
	const dataMenu = [
		{
			id: 'firstName',
			label: __( 'First Name', 'personalizewp' ),
			icon: firstNameIcon,
			action: () => toggleData( 'firstName' )
		},
		{
			id: 'lastName',
			label: __( 'Last Name', 'personalizewp' ),
			icon: lastNameIcon,
			action: () => toggleData( 'lastName' )
		},
		{
			id: 'email',
			label: __( 'User Email', 'personalizewp' ),
			icon: emailIcon,
			action: () => toggleData( 'email' )
		},
		{
			id: 'country',
			label: __( 'Country', 'personalizewp' ),
			icon: countryIcon,
			action: () => toggleData( 'country' )
		},
		{
			id: 'userRole',
			label: __( 'WordPress User Role', 'personalizewp' ),
			icon: userRoleIcon,
			action: () => toggleData( 'userRole' )
		},
		{
			id: 'userID',
			label: __( 'WordPress User ID', 'personalizewp' ),
			icon: userIdIcon,
			action: () => toggleData( 'userID' )
		},
		{
			id: 'custom',
			label: __( 'Custom Profile Field', 'personalizewp' ),
			icon: customFieldIcon,
			action: () => togglePopover()
		},
	];

	return (
		<BlockControls group="other">
			<ToolbarGroup>
				<ToolbarItem>
					{() => (
						<>
						<DropdownMenu
							icon={profileDataIcon}
							label={ __( 'Personalize Visitor Data', 'personalizewp' ) }
							controls={ dataMenu.map(
								( { id, label, icon, action } ) => ( {
									title: label,
									icon,
									isActive:
									visitorData &&
										(
											// Fixed fields
											visitorData === id ||
											// Custom fields
											visitorData.startsWith( id )
										),
									onClick: action,
								} ),
							) }
							toggleProps={ { isPressed: isActive } }
							role="menuitemcheckbox"
						/>
						{ isPopoverVisible && (
							<InlineCustomFieldUI
								visitorData={ visitorData }
								toggleData={ toggleData }
								onClose={ togglePopover }
								contentRef={ contentRef }
							/>
						) }
						</>
					)}
				</ToolbarItem>
			</ToolbarGroup>
		</BlockControls>
	);
};

// Popover of all customFields options
const InlineCustomFieldUI = ( { visitorData, contentRef, toggleData, onClose } ) => {
	const popoverAnchor = useAnchor( {
		editableContentElement: contentRef.current,
		settings: PWP_TYPE,
	} );
	const [ customField, setCustomField ] = useState( visitorData );

	const settingsData = useEntityRecord( 'personalizewp/v1', 'settings' );

	// Display a default panel with spinner when settings are loading.
	if ( settingsData.isResolving ) {
		return (
			<Popover
				className="block-editor-format-toolbar__personalizewp-popover"
				anchor={ popoverAnchor }
				onClose={ onClose }
			>
				<Spinner />
			</Popover>
		);
	}
	const settings = settingsData.record;

	// Process the custom fields into options we can use.
	const fieldOptions = [
		{
			value: '',
			label: __( '-- Select a custom profile field --', 'personalizewp' ),
		},
	].concat(
		...Array.from(settings.profile_fields).map(
			function(field) {
				const key = field.value.replace('custom_', '');
				return {
					// Ensure format of value for correct data attribute.
					value: `custom` + key.charAt(0).toUpperCase() + key.slice(1),
					label: field.label
				}
			} ).sort( (a,b) => {
				// Ensure profile fields are displayed alphabetically.
				return a.label.localeCompare( b.label );
			} )
	);

	return (
		<Popover
			className="block-editor-format-toolbar__personalizewp-popover"
			anchor={ popoverAnchor }
			onClose={ onClose }
		>
			<VStack
				as="form"
				spacing={ 4 }
				className="block-editor-format-toolbar__personalizewp-container-content"
				onSubmit={ ( event ) => {
					event.preventDefault();
					toggleData( customField );
					onClose();
				} }
			>
				<SelectControl
					label={ __( 'Custom Profile Field', 'personalizewp' ) }
					value={ customField }
					options={ fieldOptions }
					onChange={ ( field ) => setCustomField( field )	}
					__next40pxDefaultSize
					__nextHasNoMarginBottom
				/>
				<HStack alignment="right">
					<Button
						text={ __( 'Clear', 'personalizewp' ) }
						variant="link"
						onClick={ ( event ) => {
							event.preventDefault();
							// Clear out the format
							toggleData( '' );
							onClose();
						} }
						__next40pxDefaultSize
					/>
					<Button
						text={ __( 'Apply', 'personalizewp' ) }
						variant="primary"
						type="submit"
						__next40pxDefaultSize
					/>
				</HStack>
			</VStack>
		</Popover>
	);
};

// Registers the Visitor Data RichText Format with the above options.
registerFormatType( PWP_TYPE, {
	title: __( 'Personalize Visitor Data', 'personalizewp' ),
	tagName: "pwp-user-data",
	className: null,
	attributes: {
		data: 'data'
	},
	edit: VisitorDataMenu,
} );
