import TextField from "@mui/material/TextField";
import { useEffect, useRef, useState } from "react";

export function InlineEditableCell({
    buttonTitle,
    className = "",
    disabledTitle,
    displayValue,
    editable = true,
    emptyLabel = "-",
    inputProps,
    maxWidth = "100%",
    normalizeValue = (value) => String(value ?? "").trim(),
    onSave,
    saving = false,
    type = "text",
    value,
    variant = "default",
    width = "100%",
}) {
    const originalValue = String(value ?? "");
    const shownValue = displayValue ?? originalValue;
    const canEdit = Boolean(editable && !saving);
    const [editing, setEditing] = useState(false);
    const [draft, setDraft] = useState(originalValue);
    const skipBlurRef = useRef(false);

    useEffect(() => {
        if (!editing) {
            setDraft(originalValue);
        }
    }, [editing, originalValue]);

    const save = () => {
        if (skipBlurRef.current) {
            skipBlurRef.current = false;
            return;
        }
        const nextValue = normalizeValue(draft);
        setEditing(false);
        if (nextValue !== originalValue) {
            void onSave?.(nextValue);
        }
    };

    const cancel = () => {
        skipBlurRef.current = true;
        setDraft(originalValue);
        setEditing(false);
    };

    const style = {
        "--inline-edit-cell-max-width": maxWidth,
        "--inline-edit-cell-width": width,
    };

    if (!editing) {
        return (
            <span className={["inline-edit-cell", className].filter(Boolean).join(" ")} style={style}>
                <button
                    className={[
                        "inline-edit-cell__button",
                        variant === "link" ? "inline-edit-cell__button--link" : "",
                    ]
                        .filter(Boolean)
                        .join(" ")}
                    disabled={!canEdit}
                    title={canEdit ? buttonTitle : disabledTitle}
                    type="button"
                    onClick={() => {
                        if (canEdit) {
                            setEditing(true);
                        }
                    }}
                >
                    {shownValue || emptyLabel}
                </button>
            </span>
        );
    }

    return (
        <span className={["inline-edit-cell", className].filter(Boolean).join(" ")} style={style}>
            <TextField
                autoFocus
                className="inline-edit-cell__input"
                disabled={saving}
                inputProps={inputProps}
                size="small"
                type={type}
                value={draft}
                onBlur={save}
                onChange={(event) => setDraft(event.target.value)}
                onKeyDown={(event) => {
                    if (event.key === "Enter") {
                        event.preventDefault();
                        event.currentTarget.blur();
                        return;
                    }
                    if (event.key === "Escape") {
                        event.preventDefault();
                        cancel();
                    }
                }}
            />
        </span>
    );
}
