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

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

import {
	Button,
	Modal,
	MenuGroup,
	MenuItem,
} from '@wordpress/components'

import {
	useCopyToClipboard,
} from '@wordpress/compose'

import {
	useDispatch,
} from '@wordpress/data'

import {
	store as noticesStore,
} from '@wordpress/notices'

import {
	fullscreen,
	reset as resetIcon,
} from '@wordpress/icons'

import {
	CopyIcon,
	CutIcon,
	JsonView,
} from '@ska/components'

import SkaBlocksInstance from '../../../SkaBlocks'

import {
	Panel,
	PanelHeader,
	PanelBody,
	SEARCH_PLACEHOLDER,
} from '../../../tailwind/inspector-controls'

import {
	escapeVariableValue,
	handlePasteVariables,
	VARIABLES_VALUE_CLIPBOARD_PREFIX,
	type VariablesValue,
} from '..'

import {
	VariableRecordEditor,
} from '.'

const CopyValueItem: React.FC<{icon: React.JSX.Element, label: string, value: any, onCopy: () => void}> = ({
	icon,
	label,
	value,
	onCopy,
}) => {

	const {
		createSuccessNotice,
	} = useDispatch(noticesStore)

	const copyRef = useCopyToClipboard<HTMLButtonElement>(
		() => `${VARIABLES_VALUE_CLIPBOARD_PREFIX}${JSON.stringify(value)}`,
		() => {
			onCopy()
			createSuccessNotice(
				sprintf(
					__('Copied variables to clipboard. You can paste it to the "%s" input or any existing variables input.', 'ska-blocks'),
					SEARCH_PLACEHOLDER
				),
				{type: 'snackbar'}
			)
		}
	)

	return (
		<MenuItem
			icon={<div style={{width: 24, display: 'grid', placeItems: 'center'}}>{icon}</div>}
			children={label}
			label={label}
			ref={copyRef}
		/>
	)
}

interface VariablesUIProps {
	record: NonNullable<VariablesValue['record']>
	onChange: (nextRecord: VariablesValue['record']) => void
}

const VariablesUI: React.FC<VariablesUIProps> = (props) => {

	const {
		record,
		onChange,
	} = props

	const [isFullscreen, toggleFullscreen] = useReducer(isActive => !isActive, false)

	const {
		createSuccessNotice,
		createErrorNotice,
	} = useDispatch(noticesStore)

	const hasVariables = Object.keys(record).length > 0
	if(!hasVariables) {
		return null
	}

	const onVariableRecordChange = (nextRecord: VariablesValue['record'] = {}) => {
		onChange(Object.keys(nextRecord).reduce((acc, cur) => {
			const {
				value = '',
			} = nextRecord[cur]
			acc[escapeVariableValue(cur)] = {
				...nextRecord[cur],
				value: escapeVariableValue(value),
			}
			return acc
		}, {} as NonNullable<VariablesValue['record']>))
	}

	const editor = (
		<VariableRecordEditor
			help={__('CSS variables or custom rules.', 'ska-blocks')}
			className={cx({'ska-blocks--record-editor--wide': isFullscreen})}
			value={record}
			onChange={onVariableRecordChange}
			onPaste={(e: React.ClipboardEvent<HTMLInputElement>) => {

				const text = e?.clipboardData?.getData('Text')
				if(!text) {
					return
				}

				const handled = handlePasteVariables({
					content: text,
					apply: pastedRecord => {
						onChange({
							...record,
							...pastedRecord,
						})
					},
					onSuccess: () => {
						createSuccessNotice(__('Pasted variables.', 'ska-blocks'), {type: 'snackbar'})
					},
					onError: () => {
						createErrorNotice(__('Invalid value.', 'ska-blocks'), {type: 'snackbar'})
					},
				})

				if(handled) {
					e.preventDefault()
				}
			}}
		/>
	)

	return <>
		<Panel>
			<PanelHeader
				label={__('Variables', 'ska-blocks')}
				menus={<>
					<JsonView
						id='variables'
						size='small'
						modalProps={{size: 'fill'}}
						label={__('Variables value', 'ska-blocks')}
						value={() => ({
							'Generated classes': SkaBlocksInstance.tailwind.getClassNames({
								skaBlocksVariables: {
									record,
								},
							}),
							record,
						})}
					/>
					<Button
						size='small'
						icon={fullscreen}
						aria-label={__('Edit variables in a modal', 'ska-blocks')}
						onClick={toggleFullscreen}
					/>
				</>}
				actions={({onClose}) => [
					<MenuGroup key='actions'>
						<CopyValueItem
							icon={<CopyIcon size={16} />}
							label={__('Copy variables', 'ska-blocks')}
							value={record}
							onCopy={onClose}
						/>
						<CopyValueItem
							icon={<CutIcon size={16} />}
							label={__('Cut variables', 'ska-blocks')}
							value={record}
							onCopy={() => {
								onVariableRecordChange({})
								onClose()
							}}
						/>
					</MenuGroup>,
					<MenuGroup key='reset'>
						<MenuItem
							icon={resetIcon}
							children={__('Reset variables', 'ska-blocks')}
							onClick={() => {
								onVariableRecordChange({})
								onClose()
							}}
						/>
					</MenuGroup>,
				]}
			/>
			<PanelBody>
				{editor}
			</PanelBody>
		</Panel>
		{isFullscreen && (
			<Modal
				title={__('Variables', 'ska-blocks')}
				onRequestClose={toggleFullscreen}
				style={{width: 1280, maxWidth: '96vw'}}
			>
				{editor}
			</Modal>
		)}
	</>
}

export default VariablesUI
