import React, { useCallback, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { Tooltip } from '@wix/design-system';
import { StatusWarningFilledSmall } from '@wix/wix-ui-icons-common';
import { st, classes } from './EditableCell.st.css.js';
import { useCellFocusAndEditing } from './useCellFocusAndEditing';
function _EditableCell({ state, rowKey, columnId, }) {
    const { cellInteraction, clipboard } = state;
    const cellRef = useRef(null);
    const editInputRef = useRef();
    const column = state._columnMap.get(columnId);
    const keyedItem = state._getKeyedItem(rowKey);
    const resolved = column ? state.resolveCellTypeByColumnId(column.id) : null;
    const value = state.getCellDisplayValue(rowKey, columnId);
    const cellValidation = state.getCellValidation(rowKey, columnId);
    const isFocused = cellInteraction.isCellFocused(rowKey, columnId);
    const isEditing = cellInteraction.isCellEditing(rowKey, columnId);
    const isSelected = cellInteraction.isCellSelected(rowKey, columnId);
    const selectionBorder = cellInteraction.getSelectionBorder(rowKey, columnId);
    const copiedBorder = clipboard.getCopiedBorder(rowKey, columnId);
    const isEditable = state.isCellEditable(rowKey, columnId);
    const handleClick = useCallback((e) => {
        e.stopPropagation();
        state.handleCellClick(rowKey, columnId, e.shiftKey);
    }, [state, rowKey, columnId]);
    const handleDoubleClick = useCallback((e) => {
        e.stopPropagation();
        e.preventDefault();
        state.handleCellDoubleClick(rowKey, columnId);
    }, [state, rowKey, columnId]);
    // Auto-start edit if onChange fires before explicit startEdit (e.g., onOptionMarked
    // in select). startEdit resets editingValue, so it must come before setEditingValue.
    // For production cell types, consider the per-callback withEnterEdit pattern from cms-web.
    const handleChange = useCallback((newValue) => {
        if (!cellInteraction.isEditing) {
            cellInteraction.startEdit(rowKey, columnId, 'enter');
        }
        cellInteraction.setEditingValue(newValue);
    }, [cellInteraction, rowKey, columnId]);
    const handleCommit = useCallback(() => cellInteraction.commitEdit(), [cellInteraction]);
    const handleCancel = useCallback(() => cellInteraction.cancelEdit(), [cellInteraction]);
    const handleStartEdit = useCallback(() => {
        if (!cellInteraction.isEditing) {
            cellInteraction.startEdit(rowKey, columnId);
        }
    }, [cellInteraction, rowKey, columnId]);
    const cellKeyboard = useCellFocusAndEditing({
        state,
        rowKey,
        columnId,
        cellRef,
        editInputRef,
    });
    if (!column || !keyedItem || !resolved) {
        return null;
    }
    const { ViewComponent, EditComponent } = resolved;
    const showValidationIndicator = !cellValidation.valid && !isEditing;
    const showEdit = (isEditing ||
        (isFocused &&
            isEditable &&
            !state.updateItemDisabled &&
            (!!resolved.toggleValue || !!resolved.showEditWhenFocused))) &&
        EditComponent;
    const cellContent = showEdit ? (React.createElement(EditComponent, { value: cellInteraction.editingValue !== undefined
            ? cellInteraction.editingValue
            : value, onChange: handleChange, onCommit: handleCommit, onCancel: handleCancel, onStartEdit: handleStartEdit, inputRef: editInputRef, typeConfig: column.typeConfig, editTrigger: cellInteraction.editTrigger, validation: column.validation, columnId: columnId, rowKey: rowKey })) : (React.createElement(ViewComponent, { value: value, typeConfig: column.typeConfig, validation: column.validation, columnId: columnId, rowKey: rowKey }));
    // The cell type's EditWrapper (if any) stays mounted across the edit↔view
    // swap, so it can own behavior that must outlive the inline editor.
    const EditWrapper = resolved.EditWrapper;
    return (React.createElement("div", { ref: cellRef, className: st(classes.root, {
            editing: isEditing,
            focused: isFocused,
            selected: isSelected,
            invalid: !cellValidation.valid,
            typeToEdit: !!resolved.onTypeToEdit,
            showEditWhenFocused: !!resolved.showEditWhenFocused,
            growable: !!resolved.growable,
            selectionTop: selectionBorder.top,
            selectionBottom: selectionBorder.bottom,
            selectionLeft: selectionBorder.left,
            selectionRight: selectionBorder.right,
            copiedTop: copiedBorder.top,
            copiedBottom: copiedBorder.bottom,
            copiedLeft: copiedBorder.left,
            copiedRight: copiedBorder.right,
        }), onClick: handleClick, onDoubleClick: handleDoubleClick, onKeyDown: cellKeyboard.onKeyDown, role: "gridcell", "aria-selected": isSelected, "aria-readonly": !isEditable, "aria-invalid": !cellValidation.valid || undefined, tabIndex: isFocused ? 0 : -1, "data-row-key": rowKey, "data-column-id": columnId, "data-editing": isEditing || undefined },
        showValidationIndicator && (React.createElement(Tooltip, { content: cellValidation.errors?.join(', '), appendTo: "window" },
            React.createElement("span", { "data-hook": "validation-indicator" },
                React.createElement(StatusWarningFilledSmall, { className: classes.validationIndicator })))),
        EditWrapper ? (React.createElement(EditWrapper, { typeConfig: column.typeConfig, columnId: columnId, rowKey: rowKey }, cellContent)) : (cellContent)));
}
export const EditableCell = observer(_EditableCell);
//# sourceMappingURL=EditableCell.js.map