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

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

import {
	closeSmall,
} from '@wordpress/icons'

import {
	Button,
} from '@ska/components'

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

import './style.scss'

export interface ActionInputProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onChange' | 'onPaste' | 'onSubmit'> {
	id?: string
	label?: string
	hideLabelFromVision?: boolean
	placeholder?: string
	actionLabel?: string
	clearLabel?: string
	value: string
	onChange: (nextValue: string) => void
	onSubmit?: (value: string) => void
	onClear?: () => void
	onPaste?: (e: React.ClipboardEvent<HTMLInputElement>) => void
	inputProps?: Partial<TextControlProps>
	buttonProps?: typeof Button
	disabled?: boolean
	/** Disable and swap icon while loading. */
	loading?: boolean
	/** Disable the action button when the value is empty. */
	disabledWhenBlank?: boolean
	/** Highlight the input because it requires action. */
	actionable?: boolean
	/** Highlight the input because it requires a value. */
	required?: boolean
	icon?: IconType
}

const disabledProps = (isDisabled: boolean) => ({
	disabled: isDisabled,
	...(isDisabled && {
		'aria-disabled': true,
	}),
})

const ActionInput: React.FC<ActionInputProps> = ({
	id,
	className,
	label = '',
	hideLabelFromVision = true,
	placeholder = '',
	actionLabel = '',
	clearLabel = 'Clear value',
	value,
	onChange,
	onSubmit,
	onClear,
	onPaste,
	disabled = false,
	loading = false,
	disabledWhenBlank = true,
	actionable = false,
	required = false,
	inputProps = {},
	buttonProps = {},
	icon,
	...props
}) => {

	const buttonIsDisabled = loading || disabled || (disabledWhenBlank && !value)

	const hasActionButton = actionLabel && !icon
	const clearable = onClear && value

	return (
		<form
			className={cx('ska-action-input', className)}
			onSubmit={(e) => {
				e.preventDefault()
				if(onSubmit) {
					onSubmit(value)
				}
			}}
			{...props}
		>
			<div className='ska-action-input__wrapper'>
				<TextControl
					id={id}
					label={label}
					hideLabelFromVision={hideLabelFromVision}
					placeholder={placeholder}
					value={value}
					disabled={loading}
					onChange={onChange}
					onPaste={onPaste}
					{...inputProps}
					className={cx('ska-action-input__input', {
						'ska-action-input__input--has-action': hasActionButton,
						'ska-action-input__input--clearable': clearable,
						'ska-action-input__input--actionable': actionable,
						'ska-action-input__input--required': required && !value,
					}, inputProps.className)}
					__nextHasNoMarginBottom
					__next40pxDefaultSize
				/>
				{icon && (
					<Button
						type='submit'
						className='ska-action-input__icon'
						icon={icon}
						label={actionLabel}
						isBusy={loading}
						{...disabledProps(buttonIsDisabled)}
					/>
				)}
				{clearable && (
					<Button
						className='ska-action-input__icon'
						icon={closeSmall}
						label={clearLabel}
						onClick={onClear}
					/>
				)}
			</div>
			{hasActionButton && (
				<Button
					variant='primary'
					children={actionLabel}
					type='submit'
					isBusy={loading}
					{...disabledProps(buttonIsDisabled)}
					{...buttonProps}
				/>
			)}
		</form>
	)
}

export default ActionInput
