<template>
  <div class="rich-editor">
    <div v-if="editor" class="rich-editor-toolbar">
      <button type="button" :class="btn(editor.isActive('heading', { level: 2 }))" @click="editor.chain().focus().toggleHeading({ level: 2 }).run()" title="大标题">H2</button>
      <button type="button" :class="btn(editor.isActive('heading', { level: 3 }))" @click="editor.chain().focus().toggleHeading({ level: 3 }).run()" title="小标题">H3</button>
      <button type="button" :class="btn(editor.isActive('paragraph'))" @click="editor.chain().focus().setParagraph().run()" title="正文">¶</button>
      <span class="divider" />
      <button type="button" :class="btn(editor.isActive('bold'))" @click="editor.chain().focus().toggleBold().run()" title="加粗"><b>B</b></button>
      <button type="button" :class="btn(editor.isActive('italic'))" @click="editor.chain().focus().toggleItalic().run()" title="斜体"><i>I</i></button>
      <button type="button" :class="btn(editor.isActive('strike'))" @click="editor.chain().focus().toggleStrike().run()" title="删除线"><s>S</s></button>
      <span class="divider" />
      <button type="button" :class="btn(editor.isActive('bulletList'))" @click="editor.chain().focus().toggleBulletList().run()" title="无序列表">• 列表</button>
      <button type="button" :class="btn(editor.isActive('orderedList'))" @click="editor.chain().focus().toggleOrderedList().run()" title="有序列表">1. 列表</button>
      <button type="button" :class="btn(editor.isActive('blockquote'))" @click="editor.chain().focus().toggleBlockquote().run()" title="引用">" 引用</button>
      <span class="divider" />
      <button type="button" :class="btn(editor.isActive('link'))" @click="setLink" title="链接">🔗 链接</button>
      <button type="button" class="toolbar-btn" @click="addImage" title="插入图片">🖼 图片</button>
      <span class="divider" />
      <button type="button" class="toolbar-btn" @click="editor.chain().focus().undo().run()" title="撤销">↶</button>
      <button type="button" class="toolbar-btn" @click="editor.chain().focus().redo().run()" title="重做">↷</button>
      <span class="divider" />
      <button type="button" class="toolbar-btn" :class="{ active: showHtml }" @click="showHtml = !showHtml" title="源代码视图">&lt;/&gt; HTML</button>
    </div>

    <EditorContent v-show="!showHtml" :editor="editor" class="rich-editor-body" />
    <textarea
      v-show="showHtml"
      :value="modelValue"
      class="rich-editor-html"
      rows="20"
      @input="$emit('update:modelValue', $event.target.value); editor?.commands.setContent($event.target.value, false)"
    />
  </div>
</template>

<script setup>
import { EditorContent, useEditor } from '@tiptap/vue-3'
import StarterKit from '@tiptap/starter-kit'
import Link from '@tiptap/extension-link'
import Image from '@tiptap/extension-image'
import { watch, ref, onBeforeUnmount } from 'vue'

const props = defineProps({
  modelValue: { type: String, default: '' },
  placeholder: { type: String, default: '开始写作...' },
})
const emit = defineEmits(['update:modelValue'])

const showHtml = ref(false)

const editor = useEditor({
  content: props.modelValue,
  extensions: [
    StarterKit,
    Link.configure({ openOnClick: false, HTMLAttributes: { rel: 'noopener', target: '_blank' } }),
    Image,
  ],
  onUpdate: ({ editor }) => {
    emit('update:modelValue', editor.getHTML())
  },
})

watch(() => props.modelValue, (val) => {
  if (!editor.value) return
  const current = editor.value.getHTML()
  if (val !== current) editor.value.commands.setContent(val || '', false)
})

onBeforeUnmount(() => editor.value?.destroy())

function btn(active) { return { 'toolbar-btn': true, active } }

function setLink() {
  const prev = editor.value.getAttributes('link').href
  const url = window.prompt('链接 URL', prev || 'https://')
  if (url === null) return
  if (url === '') { editor.value.chain().focus().extendMarkRange('link').unsetLink().run(); return }
  editor.value.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
}

function addImage() {
  const url = window.prompt('图片 URL（可填 /uploads/ 或 /images/ 路径）')
  if (url) editor.value.chain().focus().setImage({ src: url }).run()
}
</script>

<style scoped>
.rich-editor {
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: #fff;
}

.rich-editor-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  padding: 8px;
  border-bottom: 1px solid #e5e7eb;
  background: #fafafa;
  border-radius: 4px 4px 0 0;
}

.toolbar-btn {
  padding: 4px 10px;
  font-size: 13px;
  border: 1px solid #e5e7eb;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
  color: #374151;
  transition: all 0.15s;
}
.toolbar-btn:hover { background: #f3f4f6; border-color: #3a7d44; }
.toolbar-btn.active { background: #3a7d44; color: #fff; border-color: #3a7d44; }

.divider {
  width: 1px;
  background: #e5e7eb;
  margin: 2px 4px;
}

.rich-editor-body {
  padding: 12px 14px;
  min-height: 400px;
  font-size: 14px;
  line-height: 1.7;
  color: #111827;
}
.rich-editor-body :deep(.ProseMirror) { outline: none; min-height: 380px; }
.rich-editor-body :deep(.ProseMirror:focus) { outline: none; }
.rich-editor-body :deep(h2) { font-size: 20px; font-weight: 600; margin: 18px 0 10px; color: #111827; }
.rich-editor-body :deep(h3) { font-size: 16px; font-weight: 600; margin: 14px 0 8px; color: #111827; }
.rich-editor-body :deep(p) { margin: 8px 0; }
.rich-editor-body :deep(ul), .rich-editor-body :deep(ol) { padding-left: 24px; margin: 8px 0; }
.rich-editor-body :deep(li) { margin: 4px 0; }
.rich-editor-body :deep(blockquote) {
  border-left: 3px solid #3a7d44;
  padding-left: 12px;
  color: #6b7280;
  margin: 12px 0;
}
.rich-editor-body :deep(a) { color: #3a7d44; text-decoration: underline; }
.rich-editor-body :deep(img) { max-width: 100%; height: auto; border-radius: 4px; }
.rich-editor-body :deep(strong) { font-weight: 600; }

.rich-editor-html {
  width: 100%;
  padding: 12px 14px;
  border: none;
  outline: none;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 1.6;
  resize: vertical;
  min-height: 400px;
  background: #1f2937;
  color: #d1fae5;
  border-radius: 0 0 4px 4px;
}
</style>
