<script setup lang="ts">
import { ref, watch, onMounted, nextTick } from 'vue';

const props = defineProps<{
  modelValue?: string;
}>();

const emits = defineEmits<{
  'update:modelValue': [value: string];
  change: [value: string];
}>();

const editorRef = ref<HTMLDivElement>();
const content = ref(props.modelValue || '');

// 监听外部值变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal !== content.value && editorRef.value) {
      editorRef.value.innerHTML = newVal || '';
      content.value = newVal || '';
    }
  }
);

// 内容变化处理
const handleInput = () => {
  if (editorRef.value) {
    const html = editorRef.value.innerHTML;
    content.value = html;
    emits('update:modelValue', html);
    emits('change', html);
  }
};

// 工具栏命令
const execCommand = (command: string, value?: string | boolean) => {
  document.execCommand(command, false, value as string);
  editorRef.value?.focus();
  handleInput();
};

// 格式化按钮
const formatBold = () => execCommand('bold');
const formatItalic = () => execCommand('italic');
const formatUnderline = () => execCommand('underline');

// 对齐
const alignLeft = () => execCommand('justifyLeft');
const alignCenter = () => execCommand('justifyCenter');
const alignRight = () => execCommand('justifyRight');
const alignJustify = () => execCommand('justifyFull');

// 列表
const insertUnorderedList = () => execCommand('insertUnorderedList');
const insertOrderedList = () => execCommand('insertOrderedList');

// 其他
const formatBlockquote = () => execCommand('formatBlock', 'blockquote');
const indent = () => execCommand('indent');
const outdent = () => execCommand('outdent');
const insertLink = () => {
  const url = prompt('请输入链接地址:');
  if (url) {
    execCommand('createLink', url);
  }
};
const insertCode = () => execCommand('formatBlock', 'pre');

// 撤销/重做
const undo = () => execCommand('undo');
const redo = () => execCommand('redo');

// 插入图片
const insertImage = () => {
  const url = prompt('请输入图片地址:');
  if (url) {
    execCommand('insertImage', url);
  }
};

// 插入视频
const insertVideo = () => {
  const url = prompt('请输入视频地址:');
  if (url && editorRef.value) {
    const video = document.createElement('video');
    video.controls = true;
    video.src = url;
    video.style.maxWidth = '100%';
    editorRef.value.appendChild(video);
    handleInput();
  }
};

// 段落格式
const formatParagraph = (tag: string) => {
  execCommand('formatBlock', tag);
};

onMounted(() => {
  if (editorRef.value && props.modelValue) {
    editorRef.value.innerHTML = props.modelValue;
  }
});
</script>

<template>
  <div class="rich-text-editor">
    <!-- 工具栏第一行 -->
    <div class="toolbar toolbar-row-1">
      <a-select
        :value="'p'"
        style="width: 100px"
        @change="(val) => formatParagraph(val)"
        placeholder="段落"
      >
        <a-select-option value="p">段落</a-select-option>
        <a-select-option value="h1">标题1</a-select-option>
        <a-select-option value="h2">标题2</a-select-option>
        <a-select-option value="h3">标题3</a-select-option>
      </a-select>

      <div class="toolbar-divider"></div>

      <a-button-group>
        <a-button @click="formatBold" title="粗体" size="small">
          <strong style="font-weight: bold">B</strong>
        </a-button>
        <a-button @click="formatItalic" title="斜体" size="small">
          <em style="font-style: italic">I</em>
        </a-button>
        <a-button @click="formatUnderline" title="下划线" size="small">
          <u style="text-decoration: underline">U</u>
        </a-button>
      </a-button-group>

      <div class="toolbar-divider"></div>

      <a-button-group>
        <a-button @click="alignLeft" title="左对齐" size="small">⬅</a-button>
        <a-button @click="alignCenter" title="居中" size="small">⬍</a-button>
        <a-button @click="alignRight" title="右对齐" size="small">➡</a-button>
        <a-button @click="alignJustify" title="两端对齐" size="small">⬌</a-button>
      </a-button-group>

      <div class="toolbar-divider"></div>

      <a-button-group>
        <a-button @click="insertUnorderedList" title="无序列表" size="small">•</a-button>
        <a-button @click="insertOrderedList" title="有序列表" size="small">1.</a-button>
      </a-button-group>

      <div class="toolbar-divider"></div>

      <a-button @click="formatBlockquote" title="引用" size="small">"</a-button>
      <a-button @click="outdent" title="减少缩进" size="small">◀</a-button>
      <a-button @click="indent" title="增加缩进" size="small">▶</a-button>
      <a-button @click="insertLink" title="链接" size="small">🔗</a-button>
      <a-button @click="formatBlockquote" title="引用块" size="small">[]</a-button>
      <a-button @click="insertCode" title="代码块" size="small">{}</a-button>
    </div>

    <!-- 工具栏第二行 -->
    <div class="toolbar toolbar-row-2">
      <a-button @click="undo" title="撤销" size="small">↶</a-button>
      <a-button @click="redo" title="重做" size="small">↷</a-button>
      <a-button @click="insertImage" title="图片" size="small">🖼️</a-button>
      <a-button @click="insertVideo" title="视频" size="small">📹</a-button>
      <a-button title="计数" size="small" class="counter-btn">1</a-button>
    </div>

    <!-- 编辑区域 -->
    <div
      ref="editorRef"
      class="editor-content"
      contenteditable="true"
      @input="handleInput"
      @paste="handleInput"
      placeholder="请输入文字"
    ></div>
  </div>
</template>

<style scoped lang="scss">
.rich-text-editor {
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background: #fff;
  display: flex;
  flex-direction: column;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid #d9d9d9;
  background: #fafafa;
  flex-wrap: wrap;
}

.toolbar-row-1 {
  border-bottom: 1px solid #e8e8e8;
}

.toolbar-row-2 {
  border-top: 1px solid #e8e8e8;
}

.toolbar-divider {
  width: 1px;
  height: 20px;
  background: #d9d9d9;
  margin: 0 4px;
}

.editor-content {
  min-height: 300px;
  padding: 12px;
  outline: none;
  overflow-y: auto;
  line-height: 1.6;
  color: #000;

  &:empty::before {
    content: attr(placeholder);
    color: #bfbfbf;
  }

  :deep(img) {
    max-width: 100%;
    height: auto;
  }

  :deep(video) {
    max-width: 100%;
    height: auto;
  }
}

:deep(.ant-btn) {
  border-color: #d9d9d9;
  color: #000;
  height: 28px;
  padding: 0 8px;

  &:hover {
    border-color: #40a9ff;
    color: #40a9ff;
  }
}

.counter-btn {
  background: #ffd700 !important;
  border-color: #ffd700 !important;
  color: #000 !important;
}
</style>

