import React from 'react' import { Textarea } from './textarea' import { cn } from "@/lib/utils" interface WhatsAppEditorProps { targetId: string; value: string; onChange: (value: string) => void; onKeyDown?: (e: React.KeyboardEvent) => void; placeholder?: string; className?: string; minHeight?: string; placeholders?: Record; } export const WhatsAppEditor = ({ targetId, value, onChange, onKeyDown, placeholder, className, minHeight = "140px", placeholders = {} }: WhatsAppEditorProps) => { const [suggestionState, setSuggestionState] = React.useState<{ show: boolean, query: string, position: number, activeIndex: number }>({ show: false, query: '', position: 0, activeIndex: 0 }); const textareaRef = React.useRef(null); const availableSuggestions = Object.keys(placeholders).map(k => `{{${k}}}`); const filteredSuggestions = availableSuggestions.filter(s => s.toLowerCase().includes(suggestionState.query.toLowerCase()) ); const insertSuggestion = (suggestion: string) => { if (!textareaRef.current) return; const start = suggestionState.position; const end = textareaRef.current.selectionStart; const newValue = value.substring(0, start - 1) + suggestion + value.substring(end); onChange(newValue); setSuggestionState(prev => ({ ...prev, show: false })); setTimeout(() => { if (textareaRef.current) { const newPos = start - 1 + suggestion.length; textareaRef.current.focus(); textareaRef.current.setSelectionRange(newPos, newPos); } }, 0); }; const handleKeyDown = (e: React.KeyboardEvent) => { // 0. Suggestion Navigation if (suggestionState.show) { if (e.key === 'ArrowDown') { e.preventDefault(); setSuggestionState(prev => ({ ...prev, activeIndex: (prev.activeIndex + 1) % filteredSuggestions.length })); return; } if (e.key === 'ArrowUp') { e.preventDefault(); setSuggestionState(prev => ({ ...prev, activeIndex: (prev.activeIndex - 1 + filteredSuggestions.length) % filteredSuggestions.length })); return; } if (e.key === 'Enter' || e.key === 'Tab') { e.preventDefault(); if (filteredSuggestions[suggestionState.activeIndex]) { insertSuggestion(filteredSuggestions[suggestionState.activeIndex]); } return; } if (e.key === 'Escape') { setSuggestionState(prev => ({ ...prev, show: false })); return; } } // 1. If parent provided onKeyDown, call it if (onKeyDown) onKeyDown(e); // 2. Smart Lists Logic (Enter key) if (e.key === 'Enter' && !e.shiftKey) { const textarea = e.currentTarget; const start = textarea.selectionStart; const end = textarea.selectionEnd; const textBefore = value.substring(0, start); const textAfter = value.substring(end); const lines = textBefore.split('\n'); const currentLine = lines[lines.length - 1]; const bulletMatch = currentLine.match(/^([*-] )/); const numberedMatch = currentLine.match(/^(\d+)\. /); if (bulletMatch || numberedMatch) { e.preventDefault(); const marker = bulletMatch ? bulletMatch[0] : numberedMatch![0]; if (currentLine.trim() === marker.trim()) { const newLines = [...lines]; newLines[newLines.length - 1] = ''; const newValue = newLines.join('\n') + textAfter; onChange(newValue); setTimeout(() => { textarea.selectionStart = textarea.selectionEnd = Math.max(0, start - marker.length); }, 0); } else { let nextMarker = marker; if (numberedMatch) { const nextNum = parseInt(numberedMatch[1]) + 1; nextMarker = `${nextNum}. `; } const newValue = textBefore + '\n' + nextMarker + textAfter; onChange(newValue); setTimeout(() => { textarea.selectionStart = textarea.selectionEnd = start + 1 + nextMarker.length; }, 0); } } } }; const handleChange = (e: React.ChangeEvent) => { const newVal = e.target.value; const pos = e.target.selectionStart; const char = newVal[pos - 1]; if (char === '/' || char === '@') { setSuggestionState({ show: true, query: '', position: pos, activeIndex: 0 }); } else if (suggestionState.show) { const queryStr = newVal.substring(suggestionState.position, pos); if (char === ' ' || pos < suggestionState.position) { setSuggestionState(prev => ({ ...prev, show: false })); } else { setSuggestionState(prev => ({ ...prev, query: queryStr })); } } onChange(newVal); }; return (