import './style.scss';

import { Button, ToggleControl } from '@wordpress/components';
import { useCallback, useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

import ControlsRender from '../controls-render';
import StepsWizard from './steps-wizard';

const { plugin_name: pluginName } = window.VPGutenbergVariables;

const NOTICE_LIMIT = parseInt(
	window.VPGutenbergVariables.items_count_notice_limit,
	10
);

function renderControls( props, category ) {
	return <ControlsRender { ...props } category={ category } isSetupWizard />;
}

function hasLayoutElement( element, attributes ) {
	const { layout_elements: layoutElements } = attributes;
	const checkIn = element === 'filter' ? 'top' : 'bottom';

	return (
		typeof layoutElements[ checkIn ] !== 'undefined' &&
		layoutElements[ checkIn ]?.elements.includes( element )
	);
}

function toggleLayoutElement( element, attributes ) {
	const { layout_elements: layoutElements } = attributes;
	const checkIn = element === 'filter' ? 'top' : 'bottom';

	if (
		typeof layoutElements[ checkIn ] === 'undefined' ||
		! layoutElements[ checkIn ]?.elements
	) {
		return layoutElements;
	}

	const result = JSON.parse( JSON.stringify( layoutElements ) );

	if ( hasLayoutElement( element, attributes ) ) {
		result[ checkIn ].elements = [];
	} else {
		result[ checkIn ].elements = [ element ];
	}

	return result;
}

/**
 * Component Class
 *
 * @param props
 */
export default function SetupWizard( props ) {
	const { attributes, setAttributes } = props;
	const {
		align,
		content_source: contentSource,
		items_click_action: clickAction,
		layout,
		images,
	} = attributes;

	const [ step, setStep ] = useState( 0 );
	const [ allowNextStep, setAllowNextStep ] = useState( false );
	const maxSteps = 2.5;

	// Add startup attributes.
	useEffect( () => {
		if ( ! align && ! contentSource ) {
			setAttributes( { align: 'wide' } );
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [] );

	// Set some starter attributes for different content sources.
	// And hide the setup wizard.
	const setStarterAttributes = useCallback( () => {
		let newAttributes = {};

		switch ( contentSource ) {
			case 'images':
				// Hide setup wizard once user select images.
				if ( images && images.length ) {
					newAttributes = {
						...newAttributes,
						items_count: -1,
						items_click_action: 'popup_gallery',
					};

					// Add infinite scroll to the gallery when user adds a lot of images.
					if ( layout !== 'slider' && images.length > NOTICE_LIMIT ) {
						newAttributes = {
							...newAttributes,
							items_count: NOTICE_LIMIT,
							layout_elements: {
								top: {
									elements: [],
									align: 'center',
								},
								items: {
									elements: [ 'items' ],
								},
								bottom: {
									elements: [ 'pagination' ],
									align: 'center',
								},
							},
							pagination: 'infinite',
							pagination_hide_on_end: true,
						};
					}
				}
				break;
			case 'post-based':
			case 'social-stream':
				newAttributes = {
					...newAttributes,
					layout_elements: {
						top: {
							elements: [],
							align: 'center',
						},
						items: {
							elements: [ 'items' ],
						},
						bottom: {
							elements: [ 'pagination' ],
							align: 'center',
						},
					},
				};
				break;
			// no default
		}

		// Prepare better default settings for Popup.
		// We can't change defaults of registered controls because it may break existing user galleries.
		// This is why we change it here, in the Setup Wizard.
		newAttributes = {
			...newAttributes,
			items_click_action_popup_title_source:
				contentSource === 'post-based' ? 'title' : 'item_title',
			items_click_action_popup_description_source:
				contentSource === 'post-based'
					? 'description'
					: 'item_description',
			items_click_action_popup_deep_link_pid: 'filename',
		};

		setAttributes( newAttributes );
		setAllowNextStep( true );
	}, [ contentSource, images, layout, setAttributes ] );

	useEffect( () => {
		if ( contentSource ) {
			setStarterAttributes();
		}
		// We have to check for contentSource change here because we don't want to run this on every render.
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [ contentSource ] );

	return (
		<div className={ `vpf-setup-wizard vpf-setup-wizard-step-${ step }` }>
			<StepsWizard step={ step }>
				{ /* Step 0: Content Source */ }
				<StepsWizard.Step>
					<div className="vpf-setup-wizard-title">{ pluginName }</div>
					<div
						className="vpf-setup-wizard-description"
						dangerouslySetInnerHTML={ {
							__html: __(
								'Set the common settings in the setup wizard,<br />more options will be available in the block settings.<br />Select the Content Source first:',
								'visual-portfolio'
							),
						} }
					/>
					{ renderControls( props, 'content-source' ) }
					{ renderControls( props, 'content-source-images' ) }
					{ renderControls( props, 'content-source-taxonomies' ) }
					{ renderControls( props, 'content-source-social-stream' ) }
				</StepsWizard.Step>

				{ /* Step 1: Items Style */ }
				<StepsWizard.Step>
					<div className="vpf-setup-wizard-title">
						{ __( 'Items Style', 'visual-portfolio' ) }
					</div>
					<div
						className="vpf-setup-wizard-description"
						dangerouslySetInnerHTML={ {
							__html: __(
								'Select one of the featured styles to get started.<br />More style settings will be available in the block settings.',
								'visual-portfolio'
							),
						} }
					/>
					{ renderControls( props, 'items-style' ) }
				</StepsWizard.Step>

				{ /* Step 2: Layout Elements */ }
				<StepsWizard.Step>
					<div className="vpf-setup-wizard-title">
						{ __( 'Additional Settings', 'visual-portfolio' ) }
					</div>
					<div className="vpf-setup-wizard-layout-elements">
						<div>
							<ToggleControl
								label={ __( 'Filter', 'visual-portfolio' ) }
								checked={ hasLayoutElement(
									'filter',
									attributes
								) }
								onChange={ () => {
									setAttributes( {
										layout_elements: toggleLayoutElement(
											'filter',
											attributes
										),
									} );
								} }
								__nextHasNoMarginBottom
							/>
						</div>
						<div>
							<ToggleControl
								label={ __( 'Pagination', 'visual-portfolio' ) }
								checked={ hasLayoutElement(
									'pagination',
									attributes
								) }
								onChange={ () => {
									setAttributes( {
										layout_elements: toggleLayoutElement(
											'pagination',
											attributes
										),
									} );
								} }
								__nextHasNoMarginBottom
							/>
						</div>
						<div>
							<ToggleControl
								label={ __(
									'Popup Gallery',
									'visual-portfolio'
								) }
								checked={ clickAction === 'popup_gallery' }
								onChange={ () => {
									setAttributes( {
										items_click_action:
											clickAction === 'popup_gallery'
												? 'url'
												: 'popup_gallery',
									} );
								} }
								__nextHasNoMarginBottom
							/>
						</div>
					</div>
				</StepsWizard.Step>
			</StepsWizard>

			{ /* Pagination */ }
			<div className="vpf-setup-wizard-pagination">
				{ contentSource ? (
					<>
						<div className="vpf-setup-wizard-pagination-button">
							<Button
								variant="link"
								onClick={ () => {
									// Skip Setup
									if ( step === 0 ) {
										setAttributes( {
											setup_wizard: '',
											content_source:
												attributes.contentSource ||
												'images',
										} );

										// Previous Step
									} else {
										setStep( step - 1 );
									}
								} }
							>
								{ step === 0
									? __( 'Skip Setup', 'visual-portfolio' )
									: __(
											'Previous Step',
											'visual-portfolio'
									  ) }
							</Button>
						</div>
						<div className="vpf-setup-wizard-pagination-progress">
							<div
								style={ {
									width: `${ Math.max(
										15,
										Math.min(
											100,
											( 100 * step ) / maxSteps
										)
									) }%`,
								} }
							/>
						</div>
						<div className="vpf-setup-wizard-pagination-button vpf-setup-wizard-pagination-button-end">
							<Button
								variant="primary"
								disabled={ ! allowNextStep }
								onClick={ () => {
									if ( step === 2 ) {
										setAttributes( { setup_wizard: '' } );
									} else {
										setStep( step + 1 );
									}
								} }
							>
								{ __( 'Continue', 'visual-portfolio' ) }
								<svg
									width="14"
									height="14"
									viewBox="0 0 20 20"
									fill="none"
									xmlns="http://www.w3.org/2000/svg"
									style={ { marginLeft: '5px' } }
								>
									<path
										d="M3 10H17"
										stroke="currentColor"
										strokeWidth="2"
										strokeLinecap="round"
										strokeLinejoin="round"
										fill="none"
									/>
									<path
										d="M11 4L17 10L11 16"
										stroke="currentColor"
										strokeWidth="2"
										strokeLinecap="round"
										strokeLinejoin="round"
										fill="none"
									/>
								</svg>
							</Button>
						</div>
					</>
				) : null }
			</div>
		</div>
	);
}
