/**
 * JoyRideTooltip component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { useState } from '@wordpress/element';
import { PropTypes } from 'prop-types';
import Joyride, { EVENTS } from 'react-joyride';
import { useTimeoutFn } from 'react-use';

/**
 * Internal dependencies
 */
import TourTooltip from './TourTooltip';
import { joyrideStyles, floaterProps } from './TourTooltips';

export default function JoyrideTooltip( {
	title,
	content,
	dismissLabel,
	target,
	onDismiss = () => {},
	cta = false,
	className,
	styles = {},
} ) {
	const checkIfTargetExists = () =>
		!! global.document.querySelector( target );

	const [ targetExists, setTargetExists ] = useState( checkIfTargetExists );
	const [ , cancel ] = useTimeoutFn( () => {
		if ( checkIfTargetExists() ) {
			setTargetExists( true );
			cancel();
		}
	}, 250 );

	// Joyride expects the step's target to be in the DOM immediately
	// so we need to wait for it in some cases, e.g. loading data.
	if ( ! targetExists ) {
		return null;
	}

	const steps = [
		{
			title,
			target,
			content,
			disableBeacon: true,
			isFixed: true,
			placement: 'auto',
			cta,
			className,
		},
	];

	// Provides button content as well as aria-label & title attribute values.
	const joyrideLocale = {
		last: dismissLabel,
	};

	return (
		<Joyride
			callback={ ( { type } ) => {
				if ( type === EVENTS.STEP_AFTER ) {
					// This is not strictly necessary as the tooltip will hide without it, but this allows the consumer of the component to clean up post-dismiss.
					onDismiss();
				}
			} }
			disableOverlay
			disableScrolling
			spotlightPadding={ 0 }
			floaterProps={ floaterProps }
			locale={ joyrideLocale }
			run
			steps={ steps }
			styles={ {
				...joyrideStyles,
				...styles,
				options: {
					...joyrideStyles.options,
					...styles?.options,
				},
				spotlight: {
					...joyrideStyles.spotlight,
					...styles?.spotlight,
				},
			} }
			tooltipComponent={ TourTooltip }
		/>
	);
}

JoyrideTooltip.propTypes = {
	title: PropTypes.string.isRequired,
	content: PropTypes.string,
	dismissLabel: PropTypes.string,
	target: PropTypes.string.isRequired,
	onDismiss: PropTypes.func,
	onShow: PropTypes.func,
	className: PropTypes.string,
	styles: PropTypes.object,
};

/**
 * JoyRideTooltip component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { PropTypes } from 'prop-types';
import Joyride, { EVENTS } from 'react-joyride';
import { useTimeoutFn } from 'react-use';

/**
 * WordPress dependencies
 */
import { useState } from '@wordpress/element';

/**
 * Internal dependencies
 */
import TourTooltip from './TourTooltip';
import { joyrideStyles, floaterProps } from './TourTooltips';

export default function JoyrideTooltip( {
	title,
	content,
	dismissLabel,
	target,
	onDismiss = () => {},
	cta = false,
	className,
	styles = {},
} ) {
	const checkIfTargetExists = () =>
		!! global.document.querySelector( target );

	const [ targetExists, setTargetExists ] = useState( checkIfTargetExists );
	const [ , cancel ] = useTimeoutFn( () => {
		if ( checkIfTargetExists() ) {
			setTargetExists( true );
			cancel();
		}
	}, 250 );

	// Joyride expects the step's target to be in the DOM immediately
	// so we need to wait for it in some cases, e.g. loading data.
	if ( ! targetExists ) {
		return null;
	}

	const steps = [
		{
			title,
			target,
			content,
			disableBeacon: true,
			isFixed: true,
			placement: 'auto',
			cta,
			className,
		},
	];

	// Provides button content as well as aria-label & title attribute values.
	const joyrideLocale = {
		last: dismissLabel,
	};

	return (
		<Joyride
			callback={ ( { type } ) => {
				if ( type === EVENTS.STEP_AFTER ) {
					// This is not strictly necessary as the tooltip will hide without it, but this allows the consumer of the component to clean up post-dismiss.
					onDismiss();
				}
			} }
			disableOverlay
			disableScrolling
			spotlightPadding={ 0 }
			floaterProps={ floaterProps }
			locale={ joyrideLocale }
			run
			steps={ steps }
			styles={ {
				...joyrideStyles,
				...styles,
				options: {
					...joyrideStyles.options,
					...styles?.options,
				},
				spotlight: {
					...joyrideStyles.spotlight,
					...styles?.spotlight,
				},
			} }
			tooltipComponent={ TourTooltip }
		/>
	);
}

JoyrideTooltip.propTypes = {
	title: PropTypes.string.isRequired,
	content: PropTypes.string,
	dismissLabel: PropTypes.string,
	target: PropTypes.string.isRequired,
	onDismiss: PropTypes.func,
	onShow: PropTypes.func,
	className: PropTypes.string,
	styles: PropTypes.object,
};

Update import grouping.