import React, {FC, ReactNode, useEffect, useRef} from "react";
import AutosizeInput from 'react-input-autosize';
import {lastChanged, NumberFieldType} from "./LastChanged";
import classNames from "classnames";

export type TextProps = {
    id: string,
    name?: string,
    value: string,
    onChange: (value: string) => void,
    type?: 'input' | 'textarea',
    placeholder?: string,
    fullWidth?: boolean,
    autoFocusOnUpdate?: boolean,
    inputLeft?: ReactNode,
    inputRight?: ReactNode,
    emptyMinWidth?: number,
}

export const Text: FC<TextProps> = ({
    value,
    onChange,
    name,
    id,
    type = 'input',
    placeholder,
    fullWidth,
    autoFocusOnUpdate = true,
    inputLeft,
    inputRight,
    emptyMinWidth
}) => {
    const inputRef = useRef<any>(null)
    value = typeof value !== 'string' ? '' : value; // ensure value is a string
    /**
     * Because the re-rendering seems to be too slow (that's my guess)
     * Everytime the user enters 2 or more digits at once, the input gets blurred and the second number never gets captured
     * so let's focus this everytime the value changes so that the user may add several numbers at once (eg: type the number "20")
     */
    useEffect(() => {
        /**
         * Unfortunately, due to re-renders we have to use this hack. otherwise, the range field would always focus the second input since
         * for some reason this component is unmounting and mounting on every update.
         * I know i should probably fox the root, but that could probably take DAYS which I don't have rn.
         */
        if (lastChanged.fieldType !== 'text') {
            return
        }
        if (!autoFocusOnUpdate) {
            return;
        }
        if (lastChanged.id === id && lastChanged.fieldType === 'text') {
            if (type === 'textarea') {
                inputRef.current?.focus()
                // Place cursor at the end for textarea
                const textLength = inputRef.current?.value?.length || 0
                inputRef.current?.setSelectionRange(textLength, textLength)
            } else {
                inputRef.current?.focus()
            }
        }
    }, [value])

    let text: ReactNode;

    const ringclass = "focus:!border-gray-400 focus:!ring-[3px] focus:!ring-gray-250 focus:!ring-opacity-40 focus:!ring-offset-2";
    const hasInnerComponents = typeof inputLeft !== 'undefined' || typeof inputRight !== 'undefined';
    const minWidthWhenEmpty = !fullWidth && value.length === 0 ? emptyMinWidth : undefined;
    if (type === 'input') {
        const input = <AutosizeInput
            ref={inputRef}
            type="text"
            name={name}
            value={value}
            minWidth={typeof minWidthWhenEmpty !== 'undefined' ? minWidthWhenEmpty : (fullWidth ? undefined : (hasInnerComponents ? undefined : 80))} // equivalent to min-w-20
            maxWidth={fullWidth ? undefined : 400} // prevent excessive growth
            inputStyle={{
                ...(fullWidth ? {width: '100%'} : {}),
                border: hasInnerComponents ? 'none' : '1px solid rgb(229 231 235)', // border-gray-250 equivalent
                borderRadius: hasInnerComponents ? 0 : '10px', // rounded-3 equivalent
                backgroundColor: 'transparent',
                fontSize: '14px', // text-base
                color: 'rgb(55 65 81)', // text-gray-700
                padding: hasInnerComponents ? '8px 0' : '8px 12px',
                outline: 'none',
                minHeight: 'auto'
            }}
            className={classNames({
                'w-full': fullWidth,
                'flex-1': fullWidth && hasInnerComponents,
            })}
            inputClassName={hasInnerComponents ? '' : ringclass}
            onChange={event => {
                lastChanged.id = id
                lastChanged.fieldType = 'text'
                onChange(event.target.value)
            }}
            placeholder={placeholder}
        />

        text = !hasInnerComponents ? input : <div className={classNames(
            "inline-flex items-center gap-2 rounded-3 border-px border-gray-250 bg-transparent px-3",
            "focus-within:!border-gray-400 focus-within:!ring-[3px] focus-within:!ring-gray-250 focus-within:!ring-opacity-40 focus-within:!ring-offset-2",
            {
                'w-full': fullWidth
            }
        )}>
            {typeof inputLeft !== 'undefined' && <div className="shrink-0">{inputLeft}</div>}
            {input}
            {typeof inputRight !== 'undefined' && <div className="shrink-0">{inputRight}</div>}
        </div>
    } else {
        text = <textarea
            ref={inputRef}
            name={name}
            value={value}
            onChange={event => {
                lastChanged.id = id
                lastChanged.fieldType = 'text'
                onChange(event.target.value)
            }}
            placeholder={placeholder}
            className={`w-full rounded-3 border-px border-gray-250 ${ringclass} p-4 text-base text-gray-700 resize-none`}
        />
    }
    return <div className={classNames("space-y-2", {
        'w-full': fullWidth
    })}>
        {name && <label className="block text-smaller-1 text-gray-500">{name}</label>}
        {text}
    </div>
}
