<template>
  <div class="rte">
    <div class="toolbar">
  <button type="button" @click="toggle('bold')"><b>B</b></button>
  <button type="button" @click="toggle('italic')"><i>I</i></button>
  <button type="button" @click="toggle('underline')"><u>U</u></button>
      <select v-model="heading" @change="applyHeading">
        <option :value="0">P</option>
        <option :value="1">H1</option>
        <option :value="2">H2</option>
        <option :value="3">H3</option>
      </select>
  <button type="button" @click="setAlign('left')">⟸</button>
  <button type="button" @click="setAlign('center')">⇔</button>
  <button type="button" @click="setAlign('right')">⟹</button>
      <input type="color" v-model="color" @input="setColor" />
  <button type="button" @click="openImagePicker">🖼️</button>
      <input ref="file" type="file" accept="image/*" class="hidden" @change="onUpload" />
    </div>
    <EditorContent v-if="editor" :editor="editor" class="editor" />

    <div v-if="showPicker" class="picker">
      <div class="picker-header">
        <span>{{ $t('blog.pickImage') }}</span>
        <button @click="showPicker=false">✕</button>
      </div>
      <div class="picker-actions">
        <button @click="triggerUpload">{{ $t('blog.uploadImage') }}</button>
      </div>
      <div class="grid">
        <div class="thumb" v-for="img in images" :key="img.id" @click="insertGallery(img)">
          <img :src="imageUrl(img)" :alt="img.title" />
          <div class="title">{{ img.title }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { EditorContent, Editor } from '@tiptap/vue-3';
import StarterKit from '@tiptap/starter-kit';
import TextAlign from '@tiptap/extension-text-align';
import Underline from '@tiptap/extension-underline';
import TextStyle from '@tiptap/extension-text-style';
import Color from '@tiptap/extension-color';
import Image from '@tiptap/extension-image';
import { listBlogImages, uploadBlogImage } from '@/api/blogApi.js';

export default {
  name: 'RichTextEditor',
  components: { EditorContent },
  props: { modelValue: { type: String, default: '' }, blogId: { type: [String, Number], required: true } },
  emits: ['update:modelValue'],
  data: () => ({ editor: null, heading: 0, color: '#000000', showPicker: false, images: [] }),
  mounted() {
    this.editor = new Editor({
      extensions: [StarterKit, Underline, TextStyle, Color, Image, TextAlign.configure({ types: ['heading', 'paragraph'] })],
      content: this.modelValue || '',
      editable: true,
      editorProps: {
        attributes: {
          class: 'pm-root'
        }
      },
      onUpdate: ({ editor }) => this.$emit('update:modelValue', editor.getHTML())
    });
  },
  beforeUnmount() { this.editor?.destroy?.(); },
  methods: {
    toggle(cmd) { this.editor?.chain().focus()[cmd]().run(); },
    applyHeading() {
      const level = Number(this.heading);
      const chain = this.editor?.chain().focus();
      if (level === 0) { chain.setParagraph().run(); } else { chain.toggleHeading({ level }).run(); }
    },
    setAlign(a) { this.editor?.chain().focus().setTextAlign(a).run(); },
    setColor() { this.editor?.chain().focus().setColor(this.color).run(); },
    openImagePicker: async function() {
      this.showPicker = true;
      const res = await listBlogImages(this.blogId);
      this.images = res.images || [];
    },
  imageUrl(img) { return `/api/blog/blogs/images/${img.hash}`; },
    insertGallery(img) {
      this.editor?.chain().focus().setImage?.({ src: this.imageUrl(img), alt: img.title }).run?.();
      // fallback: insert simple <img>
      if (!this.editor?.isActive('image')) {
        const html = `<img src="${this.imageUrl(img)}" alt="${img.title || ''}">`;
        this.editor.commands.insertContent(html);
      }
      this.showPicker = false;
    },
    triggerUpload() { this.$refs.file.click(); },
    async onUpload(e) {
      const file = e.target.files?.[0];
      if (!file) return;
      const img = await uploadBlogImage(this.blogId, file, { title: file.name });
      this.images.unshift(img);
    }
  },
  watch: {
    modelValue(v) { if (this.editor && v !== this.editor.getHTML()) this.editor.commands.setContent(v || '', false); }
  }
}
</script>

<style scoped>
.rte { position: relative; }
.toolbar { display:flex; gap:.5rem; align-items:center; flex-wrap:wrap; margin-bottom:.5rem; }
.hidden{ display:none }
.editor { border:1px solid #ccc; min-height:260px; padding:0; cursor:text; }
:deep(.ProseMirror) { min-height: 260px; outline: none; padding:.5rem; box-sizing: border-box; width:100%; }
:deep(.ProseMirror p) { margin: 0 0 .6rem; }
:deep(.ProseMirror p:first-child) { margin-top: 0; }
:deep(.ProseMirror-focused) { outline: 2px solid rgba(100,150,255,.35); }
.picker { position:absolute; top:2.5rem; left:0; right:0; background:#fff; border:1px solid #ccc; padding:.5rem; z-index:10; max-height:50vh; overflow:auto; }
.picker-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:.5rem; }
.picker-actions { margin-bottom:.5rem; }
.grid { display:grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap:.5rem; }
.thumb { border:1px solid #ddd; padding:.25rem; cursor:pointer; }
.thumb img { width:100%; height:90px; object-fit:cover; display:block; }
.thumb .title { font-size:.8rem; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
</style>
