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

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

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

import ButtonGroupButton, {ButtonGroupButtonProps} from './button-group-button'
export * from './button-group-button'

import ButtonGroupComponent from './button-group-component'
export {ButtonGroupComponent}
export * from './button-group-component'

import './style.scss'

const noop = () => {}

export interface ButtonGroupOption {
	label: string
	value: string
	tooltip?: string
	color?: string
}

export interface ButtonGroupProps {
	id?: string
	label?: string
	hideLabelFromVision?: boolean
	help?: string
	className?: string

	options: ButtonGroupOption[]
	value?: ButtonGroupOption['value'][]
	onChange?: (nextValue: ButtonGroupOption['value'][]) => void

	/** Display as pills. */
	pills?: boolean
	/** Full width. */
	fluid?: boolean
	/** Small size buttons. */
	isSmall?: boolean

	/** Component prepended to button group. */
	prepend?: React.ReactNode
	/** Component appended to button group. */
	append?: React.ReactNode
	/** Component to render a button. */
	// buttonComponent?: React.FC<ButtonGroupButtonProps>
	buttonComponent?: React.FC<ButtonGroupButtonProps>

	/** Use core WordPress <Button> component. */
	useDefaultButtons?: boolean
}

interface SubComponents {
	/** Button group with only one possible selection at a time. */
	Radio: typeof ButtonGroupRadio
	/** Radio button group where buttons display relevant content when selected. */
	Tabs: typeof ButtonGroupTabs
}

const ButtonGroup: React.FC<ButtonGroupProps> & SubComponents = (props) => {

	const {
		id,
		label,
		hideLabelFromVision = false,
		help,
		className,
		options = [],
		pills = false,
		fluid = false,
		prepend: Prepend = null,
		append: Append = null,
		buttonComponent: ButtonGroupButtonComponent = ButtonGroupButton,
	} = props

	const instanceId = useInstanceId(ButtonGroup, 'ska-button-group', id)

	return (
		<BaseControl
			className={cx('ska-button-group', {
				'ska-button-group--fluid': fluid,
				'ska-button-group--pills': pills,
				'ska-button-group--hide-label': hideLabelFromVision, // Passing `hideLabelFromVision` to `BaseControl` directly will produce a hidden `<label>` but there aren't any form elements for it.
			}, className)}
			label={<span id={instanceId}>{label}</span>}
			help={help}
			__nextHasNoMarginBottom
		>
			<ButtonGroupComponent aria-labelledby={instanceId}>
				{Prepend}
				{options.map((option, index) => {
					return (
						<ButtonGroupButtonComponent
							key={index}
							groupProps={props}
							option={option}
						/>
					)
				})}
				{Append}
			</ButtonGroupComponent>
		</BaseControl>
	)
}

export interface ButtonGroupRadioProps extends Omit<ButtonGroupProps, 'value' | 'onChange'> {
	value?: ButtonGroupOption['value']
	onChange?: (nextValue: ButtonGroupOption['value'] | '') => void
}

const ButtonGroupRadio: React.FC<ButtonGroupRadioProps> = ({
	className,
	value,
	onChange = noop,
	...props
}) => {
	return (
		<ButtonGroup
			className={cx('ska-button-group-radio', className)}
			value={value ? [value] : []}
			onChange={nextValues => {
				onChange(
					nextValues.length > 0
					? nextValues[nextValues.length - 1]
					: ''
				)
			}}
			{...props}
		/>
	)
}

ButtonGroup.Radio = ButtonGroupRadio

export interface ButtonGroupTabsOption extends ButtonGroupOption {
	content: React.ReactNode
}

export interface ButtonGroupTabsProps extends Omit<ButtonGroupRadioProps, 'options'> {
	options: ButtonGroupTabsOption[]
}

const ButtonGroupTabs: React.FC<ButtonGroupTabsProps> = ({
	className,
	options,
	value,
	...props
}) => {
	return <>
		<ButtonGroup.Radio
			className={cx('ska-button-group-tabs', className)}
			options={options}
			value={value}
			{...props}
		/>
		{options
			.filter(({value: v, content}) => v === value && content)
			.map(({value, content}) => (
			<BaseControl
				key={value}
				className='ska-button-group-tabs__tab'
				children={content}
				__nextHasNoMarginBottom
			/>
		))}
	</>
}

ButtonGroup.Tabs = ButtonGroupTabs

export default ButtonGroup
