import React, { useEffect, useRef, useState } from "react";
import { useDebouncedCallback } from "../../../hooks/useDebouncedCallback";
import { cls } from "../../../util";
import { focusedDisabled } from "../../../styles";
import { TextField } from "../../TextField";

export function VirtualTableNumberInput(props: {
    error?: Error;
    value: number;
    align?: "right" | "left" | "center";
    updateValue: (newValue: (number | null)) => void;
    focused: boolean;
    disabled: boolean;
}) {
    const { align = "left", value, updateValue, focused } = props;
    const propStringValue = (value && typeof value === "number") ? value.toString() : "";
    const [internalValue, setInternalValue] = useState<string | null>(propStringValue);
    const prevValue = useRef<number | null>(value);

    useEffect(() => {
        if (prevValue.current !== value && String(value) !== internalValue)
            setInternalValue(value ? value.toString() : null);
        prevValue.current = value;
    }, [value]);

    const doUpdate = React.useCallback(() => {
        if (internalValue !== propStringValue) {
            if (internalValue !== undefined && internalValue !== null) {
                const numberValue = parseFloat(internalValue);
                if (isNaN(numberValue)) return;
                updateValue(numberValue);
            } else {
                updateValue(null);
            }
        }
    }, [internalValue, value]);

    useDebouncedCallback(internalValue, doUpdate, !focused, 400);

    useEffect(() => {
        if (!focused && propStringValue !== internalValue)
            setInternalValue(value !== undefined && value !== null ? value.toString() : null);
    }, [value, focused]);

    const inputRef = React.useRef<HTMLInputElement>(null);

    useEffect(() => {
        if (inputRef.current && focused) {
            inputRef.current.focus({ preventScroll: true });
        }
    }, [focused, inputRef]);

    const regexp = /^-?[0-9]+[,.]?[0-9]*$/;

    return (
        <TextField
            inputRef={inputRef}
            invisible={true}
            size="small"
            className="w-full"
            inputClassName={cls("p-0 m-0 bg-transparent border-none outline-hidden font-normal leading-normal text-unset", focusedDisabled)}
            inputStyle={{ textAlign: align }}
            value={internalValue ?? ""}
            onChange={(evt) => {
                const newValue = evt.target.value.replace(",", ".");
                if (newValue.length === 0) setInternalValue(null);
                if (regexp.test(newValue) || newValue.startsWith("-")) setInternalValue(newValue);
            }}
        />
    );
}
