import React, { useRef, useEffect, useState, useCallback } from 'react'

function exec(cmd, value = null) {
  try {
    return document.execCommand(cmd, false, value)
  } catch (_) {
    return false
  }
}

/** Selection speichern, bevor Toolbar-Klicks sie zerstört (mousedown + preventDefault allein reicht nicht überall). */
function saveSelectionInside(editorEl) {
  const sel = window.getSelection()
  if (!sel || sel.rangeCount === 0 || !editorEl) return null
  try {
    const range = sel.getRangeAt(0)
    if (!editorEl.contains(range.commonAncestorContainer)) return null
    return range.cloneRange()
  } catch {
    return null
  }
}

function restoreSelection(range) {
  if (!range) return
  try {
    const sel = window.getSelection()
    sel.removeAllRanges()
    sel.addRange(range)
  } catch {
    /* noop */
  }
}

/** Browser: formatBlock erwartet oft Tag in Großschreibung. */
function formatBlock(tag) {
  const t = String(tag).toUpperCase()
  if (!exec('formatBlock', t)) {
    exec('formatBlock', tag.toLowerCase())
  }
}

function normalText() {
  exec('removeFormat')
  formatBlock('p')
}

/**
 * Leichter WYSIWYG (contenteditable). Wert kommt von außen zuverlässig ins DOM (Edit-Modus).
 */
export default function RichTextEditor({ value, onChange, placeholder, minHeight = '140px' }) {
  const ref = useRef(null)
  const [focused, setFocused] = useState(false)

  useEffect(() => {
    const el = ref.current
    if (!el || focused) return
    const next = value ?? ''
    if (el.innerHTML !== next) {
      el.innerHTML = next
    }
  }, [value, focused])

  const sync = useCallback(() => {
    if (!ref.current) return
    onChange(ref.current.innerHTML)
  }, [onChange])

  const run = (fn) => (e) => {
    e.preventDefault()
    e.stopPropagation()
    const el = ref.current
    if (!el) return
    const saved = saveSelectionInside(el)
    el.focus()
    restoreSelection(saved)
    try {
      document.execCommand('styleWithCSS', false, false)
    } catch {
      /* optional */
    }
    fn()
    sync()
  }

  const onLink = (e) => {
    e.preventDefault()
    e.stopPropagation()
    const el = ref.current
    if (!el) return
    const saved = saveSelectionInside(el)
    el.focus()
    restoreSelection(saved)
    const url = window.prompt('Link-URL (https://…)')
    if (url) {
      exec('createLink', url)
      sync()
    }
  }

  return (
    <div className="rich-text-editor-wrap">
      <div className="rich-text-toolbar" role="toolbar" aria-label="Formatierung">
        <button type="button" className="rte-btn" title="Fett" onMouseDown={run(() => exec('bold'))}>
          <strong>B</strong>
        </button>
        <button type="button" className="rte-btn" title="Kursiv" onMouseDown={run(() => exec('italic'))}>
          <em>I</em>
        </button>
        <button type="button" className="rte-btn" title="Unterstrichen" onMouseDown={run(() => exec('underline'))}>
          U
        </button>
        <span className="rte-sep" />
        <button type="button" className="rte-btn" title="Normaler Absatz" onMouseDown={run(normalText)}>
          Normal
        </button>
        <button type="button" className="rte-btn" title="Zwischenüberschrift" onMouseDown={run(() => formatBlock('h3'))}>
          Ü3
        </button>
        <span className="rte-sep" />
        <button
          type="button"
          className="rte-btn"
          title="Aufzählung (Mehrzeilen-Markierung möglich)"
          onMouseDown={run(() => exec('insertUnorderedList'))}
        >
          • Liste
        </button>
        <button type="button" className="rte-btn" title="Nummerierte Liste" onMouseDown={run(() => exec('insertOrderedList'))}>
          1. Liste
        </button>
        <span className="rte-sep" />
        <button type="button" className="rte-btn" title="Link einfügen" onMouseDown={onLink}>
          Link
        </button>
        <button
          type="button"
          className="rte-btn"
          title="Zeichenformatierung am Cursor entfernen"
          onMouseDown={run(() => {
            exec('removeFormat')
            exec('unlink')
          })}
        >
          ␡
        </button>
      </div>
      <div
        ref={ref}
        className="rich-text-editor"
        contentEditable
        suppressContentEditableWarning
        data-placeholder={placeholder || ''}
        style={{ minHeight }}
        onFocus={() => setFocused(true)}
        onBlur={() => {
          setFocused(false)
          sync()
        }}
        onInput={sync}
      />
    </div>
  )
}
