import {FocusEvent, ChangeEvent, KeyboardEvent} from 'react'
import {createStateOperator} from '@befe/brick-utils'
import {Dayjs} from 'dayjs'
import {handleUserInputChange} from '../handle-user-input-change'
import {InnerRangePicker} from '../inner-range-picker'

const ITEM_FORMAT_PROP = 'computedItemFormat'

export function createRangeFieldUserInput(
    comp: InnerRangePicker,
    opts: {
        isInputProp: 'isStartUserInput' | 'isEndUserInput'
        inputValueProp: 'startUserInputText' | 'endUserInputText'
        valueProp: 'startValue' | 'endValue'
        displayedProp: 'startDisplayedDate' | 'endDisplayedDate'
        onCustomChange: (value: Dayjs | null) => void
        onBlur: (e: FocusEvent) => void
    }
) {
    function formatInputValue(value: Dayjs | null) {
        return value ? value.format(comp[ITEM_FORMAT_PROP]) : ''
    }

    function getDisplayedValue() {
        const value = comp.state[opts.valueProp]
        return formatInputValue(value);
    }

    const [
        getState,
        setState,
    ] = createStateOperator(comp)

    function getValue() {
        if (comp.state[opts.isInputProp]) {
            return getState(opts.inputValueProp)
        }
        return getDisplayedValue()
    }

    return {
        formatInputValue,
        getValue,
        inputStart(e: FocusEvent) {
            const onFocus = comp.props.onFocus
            onFocus && onFocus(e)

            comp.setOpenStatus({
                open: true,
                [opts.isInputProp]: true,
            })

            setState({
                [opts.inputValueProp]: getValue(),
            })
        },
        inputEnd(e: FocusEvent) {
            comp.setOpenStatus({
                [opts.isInputProp]: false,
            })

            setState({
                [opts.inputValueProp]: getDisplayedValue(),
            })

            opts.onBlur(e)
        },
        handleChange(e: ChangeEvent) {
            const {
                displayedProp,
                valueProp,
                inputValueProp: inputTextProp,
            } = opts

            handleUserInputChange({
                e,
                comp,

                valueProp,
                itemFormatProp: ITEM_FORMAT_PROP,
                displayedProp,
                inputTextProp,
                isInputProp: opts.isInputProp,

                onCustomChange: opts.onCustomChange,
            })
        },
        handleKeyDown(e: KeyboardEvent) {
            if (e.nativeEvent.code === 'Tab') {
                comp.setState({
                    open: false,
                })
            }
        },
    }
}
