import React, { useEffect, useRef } from 'react'
import { Bold, Italic, Link2, List, ListOrdered } from 'lucide-react'
import MergeTagPicker from './MergeTagPicker'
const escapeHtml = (s) => String(s).replace(/&/g, '&').replace(//g, '>')
const isHtml = (s) => /<\/?(p|br|div|ul|ol|li|h[1-6]|strong|em|b|i|u|a|span|blockquote)\b/i.test(s || '')
/** Saved plain text (older forms) shown with its line breaks. */
const toEditorHtml = (value) => (isHtml(value) ? value : escapeHtml(value || '').replace(/\r?\n/g, '
'))
/** Editor HTML → stored value ('' when the editor only holds an empty line). */
const fromEditorHtml = (html) => (html.replace(/
| |\s|<\/?(p|div)>/gi, '') === '' ? '' : html)
/**
* Minimal rich text editor (bold, italic, link, lists) for success messages and email bodies. Stores HTML; the
* server keeps HTML as is (wp_kses_post) and adds line breaks only to plain text. Merge tags insert at the caret.
*/
export default function RichTextEditor({ value, onChange, fields, placeholder = '', allFields = true, minHeight = 140, testId, ariaLabel = 'Message' }) {
const ref = useRef(null)
const range = useRef(null)
// Sync external value changes (opening another item) without moving the caret while typing.
useEffect(() => {
const el = ref.current
if (!el) return
if (fromEditorHtml(el.innerHTML) !== (value || '') && document.activeElement !== el) el.innerHTML = toEditorHtml(value || '')
}, [value])
const emit = () => { if (ref.current) onChange(fromEditorHtml(ref.current.innerHTML)) }
const saveRange = () => {
const sel = window.getSelection()
if (sel && sel.rangeCount && ref.current && ref.current.contains(sel.anchorNode)) range.current = sel.getRangeAt(0).cloneRange()
}
const restoreRange = () => {
const el = ref.current
if (!el) return
el.focus()
const sel = window.getSelection()
if (range.current && sel) {
sel.removeAllRanges()
sel.addRange(range.current)
} else if (sel) {
const r = document.createRange()
r.selectNodeContents(el)
r.collapse(false)
sel.removeAllRanges()
sel.addRange(r)
}
}
const exec = (cmd, arg) => {
restoreRange()
document.execCommand(cmd, false, arg)
saveRange()
emit()
}
const addLink = () => {
const url = window.prompt('Link URL', 'https://')
if (url && /^(https?:|mailto:|\/|#|\{)/i.test(url.trim())) exec('createLink', url.trim())
}
const tools = [
{ id: 'bold', icon: Bold, label: 'Bold', run: () => exec('bold') },
{ id: 'italic', icon: Italic, label: 'Italic', run: () => exec('italic') },
{ id: 'link', icon: Link2, label: 'Link', run: addLink },
{ id: 'ul', icon: List, label: 'Bulleted list', run: () => exec('insertUnorderedList') },
{ id: 'ol', icon: ListOrdered, label: 'Numbered list', run: () => exec('insertOrderedList') },
]
return (