import React, { useCallback, useContext, useEffect, useRef, useState } from 'react' import { GraphContext, FlowUIContext } from '@/lib/graph/flowContext' import type { AppNode } from '@/lib/graph/nodeTypes' import { replaceNodeIdInGraph } from '@/lib/graph/flowUtils' type Props = { nodeId: string displayTitle: string } export function NodeHeaderTitle({ nodeId, displayTitle }: Props) { const graphCtx = useContext(GraphContext) const uiCtx = useContext(FlowUIContext) const nodes = graphCtx?.nodes ?? [] const setNodes = graphCtx?.setNodes const edges = graphCtx?.edges ?? [] const setEdges = graphCtx?.setEdges const renamingNodeId = uiCtx?.renamingNodeId ?? null const setRenamingNodeId = uiCtx?.setRenamingNodeId const [inputValue, setInputValue] = useState(nodeId) const inputRef = useRef(null) const isRenaming = renamingNodeId === nodeId useEffect(() => { if (isRenaming) { setInputValue(nodeId) inputRef.current?.focus() inputRef.current?.select() } }, [isRenaming, nodeId]) const applyRename = useCallback(() => { if (!setNodes || !setEdges || !setRenamingNodeId) return const newId = inputValue.trim() if (!newId || newId === nodeId) { setRenamingNodeId(null) return } const existingIds = nodes.map((n: any) => n.id) if (existingIds.includes(newId)) { return } const { nodes: nextNodes, edges: nextEdges } = replaceNodeIdInGraph(nodes, edges, nodeId, newId) setNodes(nextNodes as AppNode[]) setEdges(nextEdges) setRenamingNodeId(null) }, [nodeId, inputValue, nodes, edges, setNodes, setEdges, setRenamingNodeId]) const cancelRename = useCallback(() => { setRenamingNodeId?.(null) }, [setRenamingNodeId]) const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { if (e.key === 'Enter') { e.preventDefault() applyRename() } else if (e.key === 'Escape') { e.preventDefault() cancelRename() } }, [applyRename, cancelRename] ) if (!isRenaming) { return <>{displayTitle} } return ( setInputValue(e.target.value)} onKeyDown={handleKeyDown} onBlur={cancelRename} className="nodrag nopan flex-1 min-w-0 rounded border border-input bg-background px-1.5 py-0 text-sm font-semibold outline-none focus:ring-1 focus:ring-ring" data-slot="base-node-title" /> ) }