import * as React from 'react'
import {__, _x} from '@wordpress/i18n'
import cx from 'classnames'

import {
	useContext,
} from '@wordpress/element'

import {
	BaseControl,
	DropdownMenu,
	MenuGroup,
	MenuItemsChoice,
} from '@wordpress/components'

import {
	settings as settingsIcon,
} from '@wordpress/icons'

import {
	CommitTextControl,
	RecordEditorRecordContext,
} from '@ska/components'

import SpacingPicker from './SpacingPicker'
import ColorPicker from './ColorPicker'
import TogglePicker from './TogglePicker'

import {
	type VariableValue,
} from '../..'

import type {
	TextControlProps,
} from '@wordpress/components/build-types/text-control/types'

import './style.scss'

const noop = () => {}

const TYPE_CHOICES: {
	label: string,
	info?: string,
	value: NonNullable<VariableValue['type']>,
}[] = [
	{
		label: __('Custom', 'ska-blocks'),
		value: 'default',
	},
	{
		label: __('Spacing', 'ska-blocks'),
		value: 'spacing',
	},
	{
		label: __('Color', 'ska-blocks'),
		value: 'color',
	},
	{
		label: __('Toggle', 'ska-blocks'),
		value: 'toggle',
	},
	{
		label: __('Class', 'ska-blocks'),
		value: 'class',
	},
]

const TARGET_CHOICES: {
	label: string,
	info?: string,
	value: NonNullable<VariableValue['target']>,
}[] = [
	{
		label: __('Self', 'ska-blocks'),
		value: 'default',
	},
	{
		label: __('Parent', 'ska-blocks'),
		value: 'parent',
	},
	{
		label: __('Body', 'ska-blocks'),
		value: 'body',
	},
	{
		label: __('Root', 'ska-blocks'),
		value: 'root',
	},
]

const ACTIONS: {
	label: string,
	info?: string,
	value: string,
}[] = [
	{
		label: __('Duplicate', 'ska-blocks'),
		value: 'duplicate',
	},
]

export interface VariableValueControlProps extends Omit<TextControlProps, 'value' | 'onChange'> {
	value: VariableValue
	onChange: (nextValue: VariableValue) => void
	popoverProps?: Record<string, any>
}

const VariableValueControl: React.FC<VariableValueControlProps> = ({
	value: currentVariableValue = {},
	onChange,
	popoverProps = {},
	...textControlProps
}) => {

	const {
		index,
		key,
		duplicate,
	} = useContext(RecordEditorRecordContext)

	const {
		type,
		value: variableValue = '',
		fallbackValue = '',
		enabled = false,
		opacity = 101,
		target,
	} = currentVariableValue

	const updateValue = (nextValue: VariableValue['value']) => {
		onChange({...currentVariableValue, value: nextValue})
	}

	const updateFallbackValue = (nextValue: VariableValue['value']) => {
		onChange({...currentVariableValue, fallbackValue: nextValue})
	}

	const updateType = (nextType: VariableValue['type']) => {
		onChange({...currentVariableValue, type: nextType})
	}

	const updateTarget = (nextTarget: VariableValue['target']) => {
		onChange({...currentVariableValue, target: nextTarget})
	}

	const toggle = () => {
		onChange({...currentVariableValue, enabled: !enabled})
	}

	return (
		<BaseControl
			className={cx('ska-blocks__variable-value-control', {
				[`ska-blocks__variable-value-control--${type || 'default'}`]: true,
			})}
			__nextHasNoMarginBottom
		>
			{!type && (
				<CommitTextControl
					value={variableValue}
					onChange={updateValue}
					{...textControlProps}
				/>
			)}
			{type === 'spacing' && (
				<SpacingPicker
					value={variableValue}
					onChange={updateValue}
					{...textControlProps}
				/>
			)}
			{type === 'color' && (
				<ColorPicker
					value={variableValue}
					opacity={opacity}
					onChange={updateValue}
					onOpacityChange={(nextOpacity = 101) => {
						const {
							opacity,
							...restCurrentVariableValue
						} = currentVariableValue
						onChange({
							...restCurrentVariableValue,
							...((!isNaN(nextOpacity) && nextOpacity < 101) && {
								opacity: nextOpacity,
							}),
						})
					}}
					{...textControlProps}
				/>
			)}
			{type === 'toggle' && (
				<TogglePicker
					value={variableValue}
					fallbackValue={fallbackValue}
					enabled={enabled}
					onChange={updateValue}
					onFallbackChange={updateFallbackValue}
					onToggle={toggle}
					{...textControlProps}
				/>
			)}
			<DropdownMenu
				className='ska-blocks__variable-value-control__menu'
				label={__('Select variable value type', 'ska-blocks')}
				icon={settingsIcon}
				toggleProps={{size: 'small'}}
			>
				{({onClose}) => <>
					<MenuGroup label={_x('Value type', 'Variable value type', 'ska-blocks')}>
						<MenuItemsChoice
							choices={TYPE_CHOICES}
							value={type || 'default'}
							onHover={noop}
							onSelect={nextType => {
								updateType(nextType === 'default' ? undefined : nextType as VariableValue['type'])
								onClose()
							}}
						/>
					</MenuGroup>
					<MenuGroup label={_x('Target', 'Variable target', 'ska-blocks')}>
						<MenuItemsChoice
							choices={TARGET_CHOICES}
							value={target || 'default'}
							onHover={noop}
							onSelect={nextTarget => {
								updateTarget(nextTarget === 'default' ? undefined : nextTarget as VariableValue['target'])
								onClose()
							}}
						/>
					</MenuGroup>
					<MenuGroup>
						<MenuItemsChoice
							choices={ACTIONS}
							value=''
							onHover={noop}
							onSelect={action => {
								switch(action) {
									case 'duplicate':
										duplicate(index)
									break
								}
								onClose()
							}}
						/>
					</MenuGroup>
				</>}
			</DropdownMenu>
		</BaseControl>
	)
}

export default VariableValueControl
