<template>
  <div class="full-height column full-width">
    {{ editor.isActive('bold') }}
    <div class="row items-center q-my-sm">
      <div class="editor-item" @click="setBold" :class="{'active':editor.isActive('bold')}">
        <IconTextBold></IconTextBold>
      </div>
      <div class="editor-item" @click="setItalic" :class="{'active':editor.isActive('italic')}">
        <IconTextItalic></IconTextItalic>
      </div>
      <div class="editor-item" @click="setUnderline"  :class="{'active':editor.isActive('underline')}">
        <IconTextUnderline></IconTextUnderline>
      </div>
      <el-divider style="height: 100%; margin: 0 16px;" direction="vertical" />
      <div class="editor-item" @click="setHeaderTitle" :class="{'active':editor.isActive('heading', { level: 3 })}">
        <IconTitleLevel></IconTitleLevel>
      </div>
      <div class="editor-item" @click="setBlockquote" :class="{'active':editor.isActive('blockquote')}">
        <IconQuote></IconQuote>
      </div>
      <div class="editor-item" @click="setTextCenter" :class="{'active':editor.isActive({ textAlign: 'center' })}">
        <IconCenterAlignment></IconCenterAlignment>
      </div>
      <el-divider style="height: 100%; margin: 0 16px;" direction="vertical" />
      <div class="editor-item"  ref="buttonRef" @click="openLinkHandle">
        <IconLinkTwo></IconLinkTwo>
      </div>
      <div class="editor-item">
        <IconPicture></IconPicture>
      </div>
      <div class="editor-item" @click="setDiver">
        <IconDividingLine></IconDividingLine>
      </div>
    </div>
    <el-divider class="q-ma-none" />
    <el-scrollbar class="q-pa-lg full-width col editor-text-content" style="padding-bottom: 0;">
      <bubble-menu :editor="editor" :tippy-options="{ duration: 100 }" :should-show="shouldShowHandler" v-if="editor">
        <div class="bubble-menu row items-center" v-if="!showEditorLink">
          <span class="link cusor-pointer" @click="openLink(currentLink?.href)">{{ currentLink?.href}}</span>
          <el-divider style="height: 30px; margin: 0 8px 0 16px;background-color: #e5e5e5;" direction="vertical"/>
          <div class="editor-item" @click="editorLinkHandle">
            <IconEdit></IconEdit>
          </div>
          <div class="editor-item" @click="removeLink">
            <IconDeleteFour></IconDeleteFour>
          </div>
        </div>
        <div class="bubble-menu" style="width: 330px;" v-else>
          <div class="row items-center">
            <el-input class="link-box" v-model="linkText" prefix-icon="Link" @input="linkUrlChangeHandler"></el-input>
            <el-button class="q-ml-md" @click="setLink" :disabled="!validatorUrl">确认</el-button>
          </div>
          <div class="q-mt-md">
            <el-switch v-model="isBlank" class="short-switch" /> 在新窗口打开
          </div>
        </div>
      </bubble-menu>
      <editor-content :editor="editor" />
    </el-scrollbar>
  </div>
  
  <el-popover
    ref="popoverRef"
    placement="bottom"
    width="330px"
    :virtual-ref="buttonRef"
    :visible="linkVisible"
    virtual-triggering
    popper-style="border-radius:6px !important;">
    <div v-click-outside="onClickOutside">
      <div class="row items-center">
        <el-input class="link-box" v-model="linkText" prefix-icon="Link" @input="linkUrlChangeHandler"></el-input>
        <el-button class="q-ml-md" @click="setLink" :disabled="!validatorUrl">确认</el-button>
      </div>
      <div class="q-mt-md">
        <el-switch v-model="isBlank" class="short-switch" /> 在新窗口打开
      </div>
    </div>
  </el-popover>
</template>

<script setup>
import { EditorContent, BubbleMenu} from '@tiptap/vue-3'
import { Editor } from '@tiptap/core'
import StarterKit from '@tiptap/starter-kit'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import Highlight from '@tiptap/extension-highlight'
import Underline from '@tiptap/extension-underline'
import Heading from '@tiptap/extension-heading'
import Blockquote from '@tiptap/extension-blockquote'
import HorizontalRule from '@tiptap/extension-horizontal-rule'
import TextAlign from '@tiptap/extension-text-align'
import Link from '@tiptap/extension-link'
import { ref } from 'vue'
import { ClickOutside as vClickOutside } from 'element-plus'
import { openNewBlank } from '@/utils/common'
// import BubbleMenu from '@tiptap/extension-bubble-menu'


const textalign = TextAlign.configure({
  types: ['heading', 'paragraph'],
  alignments: ['left', 'right', 'center', 'justify'],
})
const link = Link.configure({
  openOnClick: false,
  defaultProtocol: 'https',
})
const linkText = ref('')
const isBlank = ref(false)
const buttonRef = ref()
const popoverRef = ref()
const linkVisible = ref(false)
const validatorUrl = ref(false)
const showEditorLink = ref(false)
const currentLink = ref()
const regex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(\:[0-9]+)?)(\/[a-zA-Z0-9%_.~+-]+)*\/?(\?[a-zA-Z0-9%_.,~+-=&]*)?(#[a-zA-Z0-9_-]+)?$/;
const statusList = ref({
  isBold:false,
  isItalic:false,
  isUnderline:false,
  isHeading:false,
  isBlockquote:false,
  isCenter:false,
})


const editor = new Editor({

  // register extensions
  extensions: [StarterKit, Highlight, Text, Document,Paragraph,Underline,Heading,Blockquote,textalign,HorizontalRule,link],
  // set the initial content
  content: '<p>Example Text</p>',
  // place the cursor in the editor after initialization
  autofocus: true,
  // make the text editable (but that’s the default anyway)
  editable: true,
  // disable the loading of the default CSS (which is not much anyway)
  injectCSS: true,
  
})

const setBold = () => {
  editor.chain().focus().toggleBold().run()
}
const setItalic = () => {
  editor.chain().focus().toggleItalic().run()
}
const setUnderline = () => {
  editor.chain().focus().toggleUnderline().run()
}
const setHeaderTitle = () => {
  editor.chain().focus().toggleHeading({ level: 3 }).run()
}
const setBlockquote = () => {
  editor.chain().focus().toggleBlockquote().run()
}
const setTextCenter = () => {
  if(!editor.isActive({ textAlign: 'center' }))
    editor.chain().focus().setTextAlign('center').run()
  else
    editor.chain().focus().unsetTextAlign().run()
}
const setDiver=()=>{
  editor.chain().focus().setHorizontalRule().run()
}
const onClickOutside = () => {
  if(linkVisible.value) {
    linkVisible.value=false
    editor.chain().focus()
  }
}
const openLink = (url)=>{
  openNewBlank(url)
}
const linkUrlChangeHandler = ()=>{
  validatorUrl.value = regex.test(linkText.value)
}
const setLink = ()=>{
  if(editor.isActive('link')){
    const r = editor.chain().focus().extendMarkRange('link').setLink({ href: linkText.value, target: isBlank.value?'_blank':'_self'  }).run()
    showEditorLink.value=false
    currentLink.value=editor.getAttributes('link')
  }else{
    editor.commands.setLink({ href: linkText.value, target: isBlank.value?'_blank':'_self' })
  }
  onClickOutside()
}
const removeLink = ()=>{
  if(editor.isActive('link')){
    editor.chain().focus().extendMarkRange('link').unsetLink().run()
  }
}
const openLinkHandle = ()=>{
  editor.chain().focus()
  const { from, to } = editor.state.selection;
  linkVisible.value = from != to
  if(linkVisible.value) {
    linkText.value=''
    validatorUrl.value=false
  }
}
const editorLinkHandle = ()=>{
  linkText.value=currentLink.value.href
  showEditorLink.value=true
  isBlank.value=currentLink.value.target=='_blank'
}
const shouldShowHandler = ({ editor, view, state, oldState, from, to }) => {
  if(editor.isActive('link')){
    showEditorLink.value=false
    currentLink.value=editor.getAttributes('link')
  }
  return editor.isActive('link')
}
</script>
<style>
.editor-item{
  font-size: 18px;
  padding:5px 10px;
  color: #000;
  border-radius: 4px;
  background-color: transparent;
  cursor: pointer;
  margin-left: 5px;
}
.editor-item:hover,
.editor-item.active{
  background-color: rgba(0, 0, 255, 0.05);
}
.editor-item.active{
  color:var(--el-color-primary);
}
.editor-text-content .ProseMirror,.editor-text-content .ProseMirror-static{
  font-size: 14px !important;
  font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif !important;
  
}
.link-box .el-input__wrapper{
  background-color: #f5f5f5 !important;
  color: #000 !important;
  border-radius: 6px !important;
  box-shadow: none !important;
}
.link-box .el-input__prefix{
  color: #000 !important;
}
.tiptap *{
  line-height: 1.5 !important;
}
.el-switch.short-switch .el-switch__core {
    min-width: 35px;
}
.bubble-menu {
  background-color: #FFF;
  border: 1px solid #e5e5e5;
  border-radius: 8px;
  box-shadow: 0 1px 2px 0 rgba(0,0,0,.05);
  padding: 8px;
}
.bubble-menu .link{
  font-size: 14px;
  color: #000;
  text-decoration: underline;
}
</style>