import { useMemo, useState } from 'react' import { getWordSuggestions } from '@/lib/keyManagementBIP39' import { decideAutocompleteKeyAction } from './autocompleteKeyDecision' export interface WordAutocompleteState { suggestions: string[] showSuggestions: boolean setShowSuggestions: (value: boolean) => void selectedIndex: number handleChange: (event: React.ChangeEvent) => void handleKeyDown: (event: React.KeyboardEvent) => void applySuggestion: (suggestion: string) => void } export function useWordAutocomplete(params: { value: string onChange: (value: string) => void inputRef: React.RefObject }): WordAutocompleteState { const [showSuggestions, setShowSuggestions] = useState(false) const [selectedIndex, setSelectedIndex] = useState(-1) const suggestions = useWordSuggestions(params.value) const applySuggestion = (suggestion: string): void => { applySuggestionImpl({ suggestion, onChange: params.onChange, setShowSuggestions, inputRef: params.inputRef }) } const handleChange = (event: React.ChangeEvent): void => { handleChangeImpl({ event, onChange: params.onChange, setShowSuggestions, setSelectedIndex }) } const handleKeyDown = (event: React.KeyboardEvent): void => { handleKeyDownImpl({ event, suggestions, selectedIndex, setSelectedIndex, setShowSuggestions, inputRef: params.inputRef, applySuggestion, }) } return { suggestions, showSuggestions, setShowSuggestions, selectedIndex, handleChange, handleKeyDown, applySuggestion } } function useWordSuggestions(value: string): string[] { return useMemo((): string[] => { if (value.length === 0) { return [] } return getWordSuggestions(value, 5) }, [value]) } function applySuggestionImpl(params: { suggestion: string onChange: (value: string) => void setShowSuggestions: (value: boolean) => void inputRef: React.RefObject }): void { params.onChange(params.suggestion) params.setShowSuggestions(false) params.inputRef.current?.blur() } function handleChangeImpl(params: { event: React.ChangeEvent onChange: (value: string) => void setShowSuggestions: (value: boolean) => void setSelectedIndex: (value: number) => void }): void { const newValue = params.event.target.value.trim().toLowerCase() params.setSelectedIndex(-1) params.setShowSuggestions(newValue.length > 0) params.onChange(newValue) } function handleKeyDownImpl(params: { event: React.KeyboardEvent suggestions: string[] selectedIndex: number setSelectedIndex: (value: number) => void setShowSuggestions: (value: boolean) => void inputRef: React.RefObject applySuggestion: (suggestion: string) => void }): void { const decision = decideAutocompleteKeyAction({ key: params.event.key, selectedIndex: params.selectedIndex, suggestionsCount: params.suggestions.length, }) if (decision.action === 'none') { return } params.event.preventDefault() if (decision.action === 'move') { params.setSelectedIndex(decision.nextIndex) return } if (decision.action === 'escape') { params.setShowSuggestions(false) params.inputRef.current?.blur() return } const suggestion = params.suggestions[decision.index] if (suggestion) { params.applySuggestion(suggestion) } }