/**
 * External dependencies.
 */
import { useEffect, useState } from '@wordpress/element';
import { PenLine } from 'lucide-react';
import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import {
	Button,
	Container,
	DropdownMenu,
	Label,
	Toaster,
	Tooltip,
	toast,
} from '@bsf/force-ui';
import { HexColorPicker, HexColorInput } from 'react-colorful';

/**
 * Internal dependencies.
 */
import { convertColorToShades, getContrastEndColor } from '@spectra-pro-helpers/color-converter';
import { spectraClassNames, capitalizeFirstLetter } from '@spectra-helpers';
import SettingsHeader from '@spectra-pro-admin/global-styles/components/SettingsHeader';

/**
 * Gets the color details of the default from the latest theme colors.
 *
 * @since x.x.x
 *
 * @param {string} colorVal - The color value to compare with.
 * @param {string} getBy    - The key of the value to compare to from the list of theme colors.
 * @return {Object}         - The Color object that matches, or empty.
 */
const getThemeColor = ( colorVal, getBy ) => {
	const currentThemeColors = window.spectra_admin_gs?.current_theme?.colors || [];
	return currentThemeColors.find( themeColor => colorVal === themeColor[ getBy ] ) || {};
};

/**
 * Gets the color details of the default from the latest theme colors.
 *
 * @since x.x.x
 *
 * @param {string} colorType - The color type.
 * @return {Object}          - The Color object that matches this default, or empty.
 */
const getThemeColorByDefault = ( colorType ) => getThemeColor( colorType, 'default' );

/**
 * Gets the color details of the given color from the latest theme colors.
 *
 * @since x.x.x
 *
 * @param {string} colorLabel - The color label.
 * @return {Object}           - The Color object that matches this label, or empty.
 */
const getThemeColorByLabel = ( colorLabel ) => getThemeColor( colorLabel, 'label' );

/**
 * Gets all the latest theme colors.
 *
 * @since x.x.x
 *
 * @return {Array} - The array of all theme colors, or empty.
 */
const getAllThemeColors = () => window.spectra_admin_gs?.current_theme?.colors || [];

/**
 * Gets the the required theme color, or the default color.
 *
 * @since x.x.x
 *
 * @param {string} colorType   - The color type.
 * @param {Object} colorObject - The color object to access, if any.
 * @return {Object}            - Either the color needed by the saved label, or the default color for this type.
 */
const getSystemOrThemeColor = ( colorType, colorObject ) => {
	// Get the current color of the value set, or the default of this type.
	const currentColor = colorObject || window.spectra_admin_gs?.system_variables?.colors[ colorType ] || {}
	// If the current color has a label, get the theme color by the label - else get the theme color by default.
	return currentColor.label ? getThemeColorByLabel( currentColor.label ) : getThemeColorByDefault( colorType );
};

/**
 * Render the color dropdown button and menu.
 *
 * @since x.x.x
 *
 * @param {Object} props - The component props.
 * @return {Element}     - The rendered dropdown component.
 */
const RenderColorDropdown = ( props ) => {
	// Destructure the required props.
	const {
		colorType,
		color,
		colorForThisSection,
		finalizedSystemColors,
		handleColorChange,
		setUseThemeColor,
	} = props;

	// Get all the theme colors as the dropdown options.
	const options = getAllThemeColors();

	// Set the required color object values.
	const selectedColorVariable = colorForThisSection?.variable || '';
	const selectedColorLabel = colorForThisSection?.themeLabel || '…';

	// Render the option content, with the variable name if required.
	const RenderOptionContent = ( { smallerVariable, colorLabel, colorVariable } ) => (
		<>
			<span className='capitalize'>{ colorLabel }</span>
			{/* If there's a variable, render it depending on the type (smaller variable or not). */}
			{ colorVariable && (
				<>
					{/* If this is not a smaller variable render, we can add a space. */}
					{ ! smallerVariable && ( <>&nbsp;</> ) }
					{/* Render the actual variable, with text-sm if it's supposed to be smaller. */}
					<span className={ spectraClassNames ( [
						'opacity-50 lowercase',
						smallerVariable && 'text-sm',
					] ) }>
						{ colorVariable }
					</span>
				</>
			) }
		</>
	);

	// Render the color dropdown with all options from the theme.
	return (
		<DropdownMenu className='w-full h-full'>
			<DropdownMenu.Trigger className='w-full h-full'>
				<Button
					className='relative w-full h-full p-0' style={ {
						'color': getContrastEndColor( color ),
						'background': color,
						'outlineWidth': 0, 
						'outlineColor': color,
						'--tw-ring-color': color,
					} }
					icon={ <PenLine style={ { position: 'absolute', right: '0.5rem' } }/> }
					iconPosition="right"
				>
					<RenderOptionContent colorLabel={ selectedColorLabel } colorVariable={ selectedColorVariable } />
				</Button>
			</DropdownMenu.Trigger>
			<DropdownMenu.ContentWrapper>
				<DropdownMenu.Content>
					<DropdownMenu.List arrow={ true }>
						{ options.map( ( option, index ) => {
							const shouldBeDisabled = Object.values( finalizedSystemColors ).some( ( finalizedColor ) => finalizedColor?.themeLabel === option.label );
							return(
								<DropdownMenu.Item
									key={ index }
									onClick={ () => {
										// Get the current system color, or theme color.
										const requiredThemeColor = getSystemOrThemeColor( colorType, {
											label: option.label,
											variable: option?.variable,
											value: option.value
										} );
										// Update the currently used theme color, and update the color change.
										setUseThemeColor( requiredThemeColor.label );
										handleColorChange( option.value, 'theme' );
									} }
									disabled={ shouldBeDisabled }
								>
									<RenderOptionContent smallerVariable={ true } colorLabel={ option?.label } colorVariable={ option?.variable } />
								</DropdownMenu.Item>
							);
						} ) }
					</DropdownMenu.List>
				</DropdownMenu.Content>
			</DropdownMenu.ContentWrapper>
		</DropdownMenu>
	)
};

/**
 * Render the main color display with either the hexcode input or the theme variable dropdown.
 *
 * @since x.x.x
 *
 * @param {Object} props - The component props.
 * @return {Element}     - The rendered main color display component.
 */
const MainColorDisplay = ( props ) => {
	// Destructure the required props.
	const {
		colorType,
		color, // Note that color is the color hex being edited in realtime.
		colorForThisSection, // While color for this section is the finalized color object.
		finalizedSystemColors,
		handleColorChange,
		useThemeColor,
		setUseThemeColor,
	} = props;

	// Render either the dropdown or the color input, based on whether the theme color is being used.
	const RenderedText = () => !! useThemeColor ? (
		<RenderColorDropdown { ...{
			colorType,
			color,
			colorForThisSection,
			finalizedSystemColors,
			handleColorChange,
			setUseThemeColor,
		} } />
	) : (
		<>
			<HexColorInput className='text-center w-fit' color={ color } onChange={ handleColorChange } prefixed />
			<PenLine style={ { position: 'absolute', right: '0.5rem' } }/>
		</>
	);

	// Render the main color display.
	return(
		<div
			className='relative rounded-md flex flex-wrap gap-2 items-center justify-center font-bold bg-clip-text'
			style={ {
				gridColumn: 'span 4 / span 4',
				color: getContrastEndColor( color ),
				background: color,
			} }
		>
			<RenderedText/>
		</div>
	)
};

/**
 * Render the color display item in the grid.
 *
 * @since x.x.x
 *
 * @param {Object} props - The component props.
 * @return {Element}     - The rendered color display component.
 */
const ColorDisplay = ( props ) => {
	// Destructure the required props.
	const {
		color,
		index,
	} = props;

	// If this is a filler item between the complementary and inverted colors, render the main color specifically with the half-and-half background.
	if ( 'comp-inv-filler' === color.label ) {
		return (
			<div
				className='flex items-center justify-center'
				style={ {
					background: `linear-gradient(to right, ${ color.complement } calc(50% - 0.125rem), white calc(50% - 0.125rem), white calc(50% + 0.125rem), ${ color.invert } calc(50% + 0.125rem))`,
				} }
			>
				<div style={ {
					width: '100%',
					height: '50%',
					background: color.main,
					border: '0.25rem solid white',
					borderRadius: '0.375rem',
				} } />
			</div>
		);
	} 

	// Renders a grid item for the current color.
	const RenderedColor = ( { children } ) => (
		<div
			className='relative flex flex-wrap gap-2 items-center justify-center font-bold bg-clip-text'
			style={ {
				gridColumn,
				borderRadius,
				color: getContrastEndColor( color.color ),
				background: color.color,
			} }
		>
			{ children }
		</div>
	);

	// Set a few default variables that may or may not be required.
	let RenderedText = () => null;
	let wrapWithTooltip = true;
	let gridColumn;
	let borderRadius;

	// If this is a complementary or inverted color, make it span 4, trnfrt the text, and hide the tooltip.
	if ( [ 'complement', 'inverted' ].includes( color.label ) ) {
		gridColumn = 'span 4 / span 4';
		RenderedText = () => <div className='capitalize'>{ color.label } <span className='opacity-50 lowercase'>{ `(${ color.color })` }</span></div>;
		wrapWithTooltip = false;
	}

	// If this is a starting or ending color in the grid, round the required corners.
	switch ( index ) {
		case 0:
		case 9:
			borderRadius = '0.375rem 0 0 0.375rem';
			break;
		case 8:
		case 11:
			borderRadius = '0 0.375rem 0.375rem 0';
			break;
	}

	// Render the color display with or without the tooltip.
	return wrapWithTooltip ? (
		<RenderedColor>
			<div style={ { width: '100%', height: '100%' } }>
				<Tooltip
					arrow
					content={ <span>{ color.color }</span> }
					placement="bottom"
					title={ `${ capitalizeFirstLetter( color.label ) } Color` }
					triggers={ [
						'hover'
					] }
					variant="dark"
				>
					<div style={ { width: '100%', height: '100%' } }></div>
				</Tooltip>
			</div>
		</RenderedColor>
	) : (
		<RenderedColor>
			<RenderedText/>
		</RenderedColor>
	);
};

/**
 * Render the color section on the settings page.
 *
 * @since x.x.x
 *
 * @param {Object} props - The component props.
 * @return {Element}     - The rendered color section component.
 */
const RenderColorSection = ( props ) => {

	// Destructure the required props.
	const {
		colorType,
		finalizedSystemColors,
		setFinalizedSystemColors,
		heading,
		description,
		alternate,
	} = props;

	// Get the color object for this section.
	const colorForThisSection = finalizedSystemColors[ colorType ];

	// State to identify whether this is a theme color (indicated by the label) or not (indicated by an empty string).
	const [ useThemeColor, setUseThemeColor ] = useState( colorForThisSection?.themeLabel );
	// State that is used to trigger the update via Ajax.
	const [ updateColor, setUpdateColor ] = useState( false );
	// State based on the current color's value, that is used to edit before finalization.
	const [ color, setColor ] = useState( colorForThisSection.value );
	// State to save the non-theme color whenever switching between theme and custom.
	const [ nonThemeColor, setNonThemeColor ] = useState( colorForThisSection.value );
	// State to generate and save all shades for this color.
	const [ colorShades, setColorShades ] = useState( convertColorToShades( colorForThisSection.value ) );
	// State to reference a timer for debouncing.
	const [ timerRef, setTimerRef ] = useState( null );

	// Effect to ensure that we only update the color in Ajax when the user has stopped changing colors for a while.
	useEffect( () => {
		// If update color is not set, abandon ship.
		if ( ! updateColor ) {
			return;
		}

		// Clear any existing timeout.
		if ( timerRef ) {
			clearTimeout( timerRef );
		}

		// If the current color has to be updated instantaneously, directly update it and return.
		if ( true !== updateColor ) {
			updateSystemColors( useThemeColor );
			setUpdateColor( false );
			return;
		}

		// Set a new timeout for stability check.
		const newTimer = setTimeout( () => {
			updateSystemColors( useThemeColor );
			setUpdateColor( false );
		}, 1000 );
	
		// Store the new timer reference.
		setTimerRef( newTimer );
	
		// Return the cleanup for the timeout.
		return () => {
			if ( newTimer ) {
				clearTimeout( newTimer );
			}
		};
	}, [ color ] );

	// An Ajax event to update the system color variables.
	const updateSystemColors = ( themeColorLabel ) => {
		// Create a new form.
        const formData = new window.FormData();

		// Check if the current theme color needs to be fetched for this color.
		const currentThemeColor = themeColorLabel ? getThemeColorByLabel( themeColorLabel ) : {};

		// Append the required data to send.
        formData.append( 'action', 'spectra_pro_gs_system_color_variables' );
        formData.append( 'security', window.spectra_admin_gs.ajax_nonce );
        formData.append( 'type', colorType );
        formData.append( 'color', color.toLowerCase() );
		formData.append( 'theme_color_label', themeColorLabel );
		formData.append( 'theme_variable', currentThemeColor?.variable || 'none' );

		// Fetch the data from the Ajax call.
        apiFetch( {
            url: window.spectra_admin_gs.ajax_url,
            method: 'POST',
            body: formData,
        } ).then( ( fetched ) => {
			// If the response is not successful, or the hexcode was not sent, run the error toast.
			if ( ! fetched?.success || ! fetched?.data?.saved_color?.hexcode ) {
				toast.error( fetched?.data?.title || __( 'Color Not Saved.', 'spectra-pro' ), { description: fetched?.data?.description  } );
			}

			// Get the fetched data.
			const data = fetched.data;

			// Update the system colors to overwrite the required color with the new details.
			const updatedSystemColors = {
				...finalizedSystemColors,
				[ colorType ]: {
					value: data.saved_color.hexcode,
					variable: data.saved_color?.variable || false,
					themeLabel: data.saved_color?.theme_label,
				}
			};

			// Format the updated options for the localized system variables.
			const localizedSystemColors = {
				...( window?.spectra_admin_gs?.system_variables?.colors || {} ),
				[ colorType ]: {
					hexcode: data.saved_color.hexcode,
					variable: data.saved_color?.variable || false,
					theme_label: data.saved_color?.theme_label,
				}
			}

			// If the color does not have a variable (some themes do not), then remove the variable key from this color
			if ( ! data.saved_color?.variable ) {
				delete updatedSystemColors[ colorType ].variable;
			}
			
			// Set the finalized colors, and update the localized colors as well.
			setFinalizedSystemColors( { ...updatedSystemColors } );
			window.spectra_admin_gs.system_variables.colors = { ...localizedSystemColors };

			// Run the success toast.
			toast.success( data.title, { description: data.description } );
        } ).catch( e => {
			// If the error thrown is not formatted as an error, make it one.
			if ( ! ( e instanceof Error ) ) {
				e = new Error( e );
			}
			console.error( e ); // eslint-disable-line no-console
			toast.error( __( 'Something went wrong.', 'spectra-pro' ), { description: e.message } );
		} );
	};

	// Function to update the color when the change is complete.
	// Note that colorType will trigger an instant update without debounce. This is used when switching between theme colors and custom.
	const handleColorChange = ( newColor, newColorType = false ) => {
		// If the user is editing color, and has typed in a 3 digit hexcode, abandon ship.
		if ( ! newColorType && /^#[0-9A-Fa-f]{3}$/.test( newColor ) ) {
			// This makes it easier to add proper hex colors without being blurred out of focus on a valid 3 digit hexcode.
			return;
		}
		// Set the new color, and the new color shades - then set the flag to update the system color via Ajax.
		setColor( newColor );
		setColorShades( convertColorToShades( newColor ) );
		setUpdateColor( newColorType || true );
	};

	// Collection of styles to render the color picker area either on the left (default) or right (alternate).
	const colorPickerStyles = alternate ? {
		gridRow: '1 / span 3',
		gridColumn: '5 / span 2',
		justifyContent: 'flex-end',
	} : {
		gridRow: 'span 3 / span 3',
		gridColumn: 'span 2 / span 2',
		justifyContent: 'flex-start',
	};

	// Ordered array indicating how the color shades should be organized.
	const orderOfColorShades = [
		'near-black',
		'darkest',
		'darker',
		'dark',
		'main',
		'light',
		'lighter',
		'lightest',
		'near-white',
		'complement',
		'invert',
	];

	// An array of the color shades organized by the required order.
	const orderedColorShades = [ ...colorShades ].sort( ( colorOne, colorTwo ) => {

        // If the first item is unknown, move it after the known types.
        const colorOneIndex = orderOfColorShades.indexOf( colorOne.label );        
        if ( colorOneIndex === -1 ) return 1;

        // If the second item is unknown, move it after the known types.
        const colorTwoIndex = orderOfColorShades.indexOf( colorTwo.label );
        if ( colorTwoIndex === -1 ) return -1;

        // Sort the items based on the required positioning.
        return colorOneIndex - colorTwoIndex;
    } );

	// Split the complement and inverted shades with a segment in the middle that contains the main color.
	orderedColorShades.splice( 10, 0, {
		label: 'comp-inv-filler',
		main: orderedColorShades[4].color,		
		complement: orderedColorShades[9].color,
		invert: orderedColorShades[10].color,
	} );

	// Render the color section.
	return (
		<>
			{/* Render the header, with the theme and custom buttons. */}
			<SettingsHeader
				heading={ heading }
				description={ description }
				help={ !! useThemeColor
					? __( 'Click on the variable name to change the color.', 'spectra-pro' )
					: __( 'Use the picker, or input a hex value to change the color.', 'spectra-pro' )
				}
			>
				<div
					className="flex gap-px justify-center items-center rounded-sm overflow-hidden"
					style={ { border: '1px solid #e5e7eb', borderRadius: '0.25rem', background: '#e5e7eb' } }
				>
					<button
						className={ `${
							!! useThemeColor
								? 'text-text-inverse bg-background-brand'
								: 'text-text-secondary bg-white'
						} p-2 cursor-pointer` }
						style={ { border: 'none' } }
						onClick={ () => {
							const requiredThemeColor = getSystemOrThemeColor( colorType, {
								label: colorForThisSection.themeLabel,
								variable: colorForThisSection?.variable,
								value: colorForThisSection.value
							} );
							setUseThemeColor( requiredThemeColor.label );
							setNonThemeColor( color );
							handleColorChange( requiredThemeColor?.value || color, 'theme' );							
						} }
					>
						{ __( 'Theme', 'spectra-pro' ) }
					</button>
					<button
						className={ `${
							!! useThemeColor
								? 'text-text-secondary bg-white'
								: 'text-text-inverse bg-background-brand'
						} p-2 cursor-pointer` }
						style={ { border: 'none' } }
						onClick={ () => {
							setUseThemeColor( '' );
							handleColorChange( nonThemeColor, 'custom' );
						} }
					>
						{ __( 'Custom', 'spectra-pro' ) }
					</button>
				</div>
			</SettingsHeader>
			{/* Render the color display container. */}
			<Container align="center" className="mb-0.5 w-full flex justify-between">
				<Container.Item className="w-full flex flex-col gap-4">
					<div className='grid grid-cols-6 grid-rows-3 gap-2'>
						<div className='flex' style={ colorPickerStyles }>
							{/* If this is a theme color, render the name of the theme - else render the color picker. */}
							{ !! useThemeColor ? (
								<div
									className='flex items-center justify-center flex-col rounded-md bg-background-secondary'
									style={ { width: '200px', height: '200px' } }
								>
									<Label className="font-semibold mb-1" size="md">
										{ window.spectra_admin_gs?.current_theme?.name || __( 'Theme', 'spectra-pro' ) }
									</Label>
									<Label className="m-0 font-normal" size="sm" tag="p" variant="help">
										{ __( 'Current Theme', 'spectra-pro' ) }
									</Label>
								</div>
							) : (
								<HexColorPicker color={ color } onChange={ ( value ) => handleColorChange( value ) } />
							) }
						</div>
						{/* Render the main color display grid item. */}
						<MainColorDisplay { ...{
							colorType,
							color,
							colorForThisSection,
							finalizedSystemColors,
							handleColorChange,
							useThemeColor,
							setUseThemeColor,
						} }/>
						{/* Then render the grid of shades, including complementary and inverted. */}
						<div className='grid grid-rows-20' style={ {
							gridTemplateColumns: 'repeat(9, minmax(0, 1fr))',
							gridColumn: 'span 4 / span 4',
							gridRow: 'span 2 / span 2',
							rowGap: '0.5rem',
							columnGap: 0,
						} }>
							{ orderedColorShades.map( ( colorVariant, index ) => (
								<ColorDisplay
									key={ index }
									color={ colorVariant }
									index={ index }
								/>
							) ) }
						</div>
					</div>
				</Container.Item>
			</Container>
		</>
	);
}

/**
 * Render the color preview circles.
 *
 * @since x.x.x
 *
 * @param {Object} props - The component props.
 * @return {Element}     - The rendered color preview component.
 */
const ColorPreview = ( props ) => {
	// Destructure the required props.
	const { previewColors } = props;

	// Create a common variable for calculation for the color preview element.
	const previewPadding = {
		value: 1,
		unit: 'rem',
	};

	// Create a common variable for the adminbar.
	const adminbarHeight = {
		value: 32,
		unit: 'px',
	};

	// Render the color preview section.
	return (
		<>
			{/* The sticky color preview element. */}
			<div style={ {
				position: 'sticky',
				top: `${ adminbarHeight.value * 1.25 }${ adminbarHeight.unit }`,
				alignSelf: 'self-end',
				zIndex: 2,
				boxSizing: 'border-box',
				height: `${ previewPadding.value * 4 }${ previewPadding.unit }`,
				padding: `${ previewPadding.value }${ previewPadding.unit }`,
				margin: `-${ previewPadding.value }${ previewPadding.unit }`,
				background: 'rgba(255,255,255,0.75)',
				borderRadius: '4px',
				backdropFilter: 'blur(20px)',
			} }>
				<Container
					align="center"
					gap="sm"
				>
					{/* Render all the color preview circles. */}
					{ previewColors.map( ( previewColor, index ) => {
						// Set the color as the outline if it is dark, else set a dark gray outline if it is light;
						const outlineColor = getContrastEndColor( previewColor.value, previewColor.value, '#9ca3af' );
						// Then render the color preview with a tooltip indicating the color variable or hex.
						return(
							<Container.Item key={ index }>
								<Tooltip
									arrow
									content={ <span>{ previewColor?.variable || previewColor.value }</span> }
									placement="bottom"
									title={ `${ capitalizeFirstLetter( previewColor.type ) } Color` }
									triggers={ [
										'hover'
									] }
									variant="dark"
								>
										<div
											className="overflow-hidden rounded-full w-8 h-8 transition-all outline outline-offset-2"
											style={ {
												backgroundColor: previewColor.value,
												outline: `2px solid ${ outlineColor }`,
												outlineOffset: '2px',
												border: `1px solid ${ outlineColor }`,
											} }
										/>
								</Tooltip>
							</Container.Item>
						);
					} ) }
				</Container>
			</div>
			{/* The heading next to the sticky color preview element. */}
			<div style={ {
				marginTop: `-${ previewPadding.value * 3 }${ previewPadding.unit }`, // Minus the height, and half the overall padding of the preview.
			} }>
				<SettingsHeader heading={ 'Current Palette' } className="w-0"/>
			</div>
		</>
	);
};

/**
 * Render the system color variables setting page.
 *
 * @since x.x.x
 *
 * @return {Element} - The rendered color variables component.
 */
const SystemColorVars = () => {

	// Get the localized system color variables.
	const savedColors = window.spectra_admin_gs?.system_variables?.colors;

	// Create the state that will store all the finalized system colors.
	const [ finalizedSystemColors, setFinalizedSystemColors ] = useState( {
		primary: {
			value: savedColors?.primary?.hexcode || '#5733ff',
			variable: savedColors?.primary?.variable || undefined,
			themeLabel: savedColors?.primary?.theme_label || '',
		},
		secondary: {
			value: savedColors?.secondary?.hexcode || '#dedcff',
			variable: savedColors?.secondary?.variable || undefined,
			themeLabel: savedColors?.secondary?.theme_label || '',
		},
		base: {
			value: savedColors?.base?.hexcode || '#020617',
			variable: savedColors?.base?.variable || undefined,
			themeLabel: savedColors?.base?.theme_label || '',
		},
	} );

	// Create a simple array state that will contain the color preview details.
	const [ previewColors, setPreviewColors ] = useState( [] );

	// Effect to update the preview colors whenever the finalized colors has been updated.
	useEffect( () => {
		const updatedPreviewColors = Object.entries( finalizedSystemColors ).map( ( [ previewColorType, previewColor ] ) => ( {
			type: previewColorType,
			value: previewColor?.value,
			variable: previewColor?.variable,
		} ) );
		setPreviewColors( [ ...updatedPreviewColors ] );
	}, [ finalizedSystemColors ] );

	// Render a simple divider.
	const Divider = () => <hr className="w-full border-b-0 border-x-0 border-t border-solid border-t-border-subtle" />;

	// Render the system color settings page.
	return (
		<>
			<Toaster position="top-right" design="stack" theme="dark" autoDismiss={ true } dismissAfter={ 2000 } />
			<ColorPreview { ...{ previewColors } }/>
			<Divider/>
			<RenderColorSection { ...{
				colorType: 'primary',
				finalizedSystemColors,
				setFinalizedSystemColors,
				heading: __( 'Primary Color', 'spectra-pro' ),
				description: __( 'This is your brand\'s main color.', 'spectra-pro' ),
			} } />
			<Divider/>
			<RenderColorSection { ...{
				colorType: 'secondary',
				finalizedSystemColors,
				setFinalizedSystemColors,
				heading: __( 'Secondary Color', 'spectra-pro' ),
				description: __( 'This is your brand\'s second prominent color.', 'spectra-pro' ),
				alternate: true,
			} } />
			<Divider/>
			<RenderColorSection { ...{
				colorType: 'base',
				finalizedSystemColors,
				setFinalizedSystemColors,
				heading: __( 'Base Color', 'spectra-pro' ),
				description: __( 'This is your brand\'s base color, mostly used for backgrounds or text.', 'spectra-pro' ),
			} } />
		</>
	);
};

// Export the SystemColorVars by default.
export default SystemColorVars;
