/**
 * External dependencies.
 */
import { BlockControls, URLPopover } from '@wordpress/block-editor';
import { ToolbarGroup, ToolbarButton } from '@wordpress/components';
import { useSelect } from '@wordpress/data';
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useAnchor } from '@wordpress/rich-text';

/**
 * Internal dependencies.
 */
import DynamicContent from '@spectra-pro-extensions/dynamic-content/components/DynamicContent';
import { isAllowedBlock } from '@spectra-pro-extensions/dynamic-content/utils/helpers';
import blockIcons from '@spectra-pro-helpers/block-icons';

/**
 * Renders a toolbar button to toggle the dynamic content configuration popover.
 *
 * Displays a button in the block editor toolbar for supported blocks, which opens a
 * popover for configuring dynamic content. The button is only shown for allowed blocks
 * and manages the visibility of the popover.
 *
 * @since x.x.x
 *
 * @param {Object}   props            - The component props.
 * @param {boolean}  props.isActive   - Whether the dynamic content format is active.
 * @param {Object}   props.contentRef - Reference to the content element for anchoring.
 * @param {Object}   props.value      - The rich text value object from the block editor.
 * @param {Function} props.onChange   - Callback to update the rich text value.
 * @return {Element|null} The toolbar button and popover, or null if the block is not supported.
 */
const DynamicContentButton = ( { isActive, contentRef, value, onChange } ) => {
	// State to manage popover visibility.
	const [ isPopoverVisible, setIsPopoverVisible ] = useState( false );
	// Track manual close to prevent auto-reopen.
	const [ manuallyClosedAt, setManuallyClosedAt ] = useState( null );
	// Track previous active state.
	const [ wasActive, setWasActive ] = useState( false );

	// Create an anchor reference for the popover based on the content selection.
	const anchorRef = useAnchor( { ref: contentRef, value } );

	// Get the currently selected block from the block editor.
	const selectedBlock = useSelect( ( select ) => select( 'core/block-editor' ).getSelectedBlock(), [] );

	// Handle popover visibility based on format active state.
	useEffect( () => {
		if ( isActive ) {
			const now = Date.now();
			// Check if this is a transition from inactive to active.
			const isNewActivation = ! wasActive;
			const notRecentlyClosed = ! manuallyClosedAt || now - manuallyClosedAt > 300;

			if ( isNewActivation && notRecentlyClosed ) {
				setIsPopoverVisible( true );
			}
		} else {
			setIsPopoverVisible( false );
			// Reset manual close tracking when format becomes inactive.
			setManuallyClosedAt( null );
		}
		// Update previous state.
		setWasActive( isActive );
	}, [ isActive ] );

	// Return null if the selected block is not supported for dynamic content.
	if ( ! isAllowedBlock( selectedBlock ) ) {
		return null;
	}

	/**
	 * Closes the popover.
	 *
	 * @since x.x.x
	 *
	 * @param {boolean} isAfterApply - Whether the popover is closing after applying changes
	 * @return {void}
	 */
	const onClose = ( isAfterApply = false ) => {
		setIsPopoverVisible( false );
		if ( isAfterApply ) {
			// Track manual close to prevent auto-reopen.
			setManuallyClosedAt( Date.now() );
		}
	};

	/**
	 * Toggles the visibility of the popover.
	 *
	 * @since x.x.x
	 *
	 * @return {void}
	 */
	const onToggle = () => {
		const newVisibility = ! isPopoverVisible;
		setIsPopoverVisible( newVisibility );
		// Reset manual close tracking when opening via toolbar.
		if ( newVisibility ) {
			setManuallyClosedAt( null );
		}
	};

	return (
		<BlockControls>
			<ToolbarGroup>
				{ /* Toolbar button to toggle the dynamic content popover */ }
				<ToolbarButton
					icon={ wasActive ? blockIcons.dynamic_content( false ) : blockIcons.dynamic_content() }
					label={ __( 'Dynamic Content', 'spectra-pro' ) }
					onClick={ onToggle }
					isActive={ isActive }
				/>
			</ToolbarGroup>
			{ /* Show popover when visible */ }
			{ isPopoverVisible && (
				<URLPopover anchor={ anchorRef } focusOnMount={ false } className="spectra-pro-dynamic-content-popover">
					<DynamicContent value={ value } onChange={ onChange } onClose={ onClose } />
				</URLPopover>
			) }
		</BlockControls>
	);
};

export default DynamicContentButton;
