import * as React from 'react'
import cx from 'classnames'

import {
	useState,
	useEffect,
	useRef,
} from '@wordpress/element'

import {
	TextControl,
} from '@wordpress/components'

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

import './style.scss'

export interface CommitTextControlProps extends Omit<TextControlProps, 'value'> {
	value?: string
}

/** TextControl that invokes `onChange` on Enter or blur not when typing. */
const CommitTextControl: React.FC<CommitTextControlProps> = ({
	value: inputValue = '',
	onChange,
	...props
}) => {

	const [value, setValue] = useState(inputValue)
	const modified = inputValue !== value
	const valueRef = useRef(value)

	useEffect(() => {
		valueRef.current = value
	}, [value])

	useEffect(() => {
		if(inputValue !== valueRef.current) {
			setValue(inputValue)
		}
	}, [inputValue])

	const commitValue = () => {
		if(inputValue !== value) {
			onChange(value)
		}
	}

	const resetValue = () => {
		if(value !== inputValue) {
			setValue(inputValue)
		}
	}

	return (
		<TextControl
			{...props}
			value={value}
			onChange={setValue}
			className={cx(props.className, 'ska-components__commit-text-control', {
				'ska-components__commit-text-control--modified': modified,
			})}
			onKeyDown={e => {

				switch(e.key) {

					case 'Enter':
						e.preventDefault()
						e.stopPropagation()
						commitValue()
					break

					case 'Escape':
						e.preventDefault()
						e.stopPropagation()
						resetValue()
					break
				}
			}}
			onBlur={commitValue}
			__nextHasNoMarginBottom
			__next40pxDefaultSize
		/>
	)
}

export default CommitTextControl
