import React, { FC, ReactNode, useEffect, useRef, useState } from "react";
import { TextInput } from "@mantine/core";
import { Styles } from "@mantine/core/lib/core/styles-api/styles-api.types";

type Props = {
    value?: string;
    onChange: (value: string) => void;
    placeholder?: string;
    getChildren: (startEditing: () => void) => ReactNode;
    inputStyles?: Styles<any>;
};

const InPlaceInputDesktop: FC<Props> = ({
    onChange,
    placeholder,
    inputStyles,
    getChildren,
    value = "",
}) => {
    const [isWriting, setIsWriting] = useState<boolean>(false);
    const [localValue, setLocalValue] = useState<string>(value);
    const inputRef = useRef<HTMLInputElement>(null);

    useEffect(() => {
        if (isWriting && inputRef.current) {
            setLocalValue(value);
            inputRef.current.focus();
        }
    }, [isWriting]);

    useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
            if (
                isWriting &&
                inputRef.current &&
                !inputRef.current.contains(event.target as Node)
            ) {
                onCompleteCreating();
            }
        };

        document.addEventListener("mousedown", handleClickOutside);
        return () =>
            document.removeEventListener("mousedown", handleClickOutside);
    }, [isWriting, localValue]);

    const onStartCreating = () => {
        setLocalValue(localValue);
        setIsWriting(true);
    };

    const onCancelCreating = () => {
        setIsWriting(false);
    };

    const onCompleteCreating = () => {
        const val = localValue.trim();
        if (val) {
            onChange(val);
        }
        setIsWriting(false);
    };

    if (isWriting) {
        return (
            <TextInput
                ref={inputRef}
                placeholder={placeholder}
                variant={"unstyled"}
                value={localValue}
                onChange={e => setLocalValue(e.target.value)}
                onKeyDown={e => {
                    e.stopPropagation();
                    if (e.key === "Enter") onCompleteCreating();
                    if (e.key === "Escape") onCancelCreating();
                }}
                styles={inputStyles}
                miw={150}
            />
        );
    }

    return getChildren(onStartCreating);
};

export default InPlaceInputDesktop;
