<template>
  <div
    class="flex size-full flex-col overflow-hidden rounded-xl bg-[#f2f4f7] px-3 py-2 shadow"
  >
    <div
      class="flex items-center gap-2 py-1 text-xs font-semibold text-gray-700"
    >
      <div>回复</div>
      <div class="ml-auto">{{ state.textCount }}</div>
      <varsPopover :node="node" @setVars="setVars">
        <el-tooltip content="变量" placement="top">
          <SvgIcon name="vars" color="#364153" size="16" />
        </el-tooltip>
      </varsPopover>
      <el-tooltip content="复制" placement="top">
        <SvgIcon
          class="__hover"
          color="#364153"
          name="copy"
          size="16"
          @click="onCopy(ref_textarea.innerText)"
        />
      </el-tooltip>
    </div>
    <div class="text-text-secondary flex-1 overflow-y-auto py-1 text-[13px]">
      <div
        class="break-all"
        style="line-height: 1.5"
        ref="ref_textarea"
        contenteditable="true"
        @input="updateMarkdown"
        @paste="handlePaste"
      ></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  computed,
  onMounted,
  reactive,
  h,
  render,
  createApp,
  watch,
} from 'vue'
import { copy } from '@/utils/czr-util'
import { ElMessage } from 'element-plus'
import SvgIcon from '@/components/SvgIcon/index.vue'
import varsPopover from '@/views/workflow/instance/component/vars/vars-popover.vue'
import paramValue from './param-value.vue'
import { useWorkflowStore } from '@/stores'

const WorkflowStore = useWorkflowStore()
const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  modelValue: {
    type: String,
    default: '',
  },
  node: {},
})
const state = reactive({
  textCount: 0,
  optionsMap: new Map(),
})
const ref_textarea = ref()
watch(
  () => props.node,
  (n) => {
    if (n) {
      const all = WorkflowStore.getInVars(n)
      const map = new Map()
      all.forEach((p) => {
        p.options.forEach((v) => {
          map.set(v.nodeId, v)
        })
      })
      state.optionsMap = map
    }
  },
  { immediate: true },
)
const updateMarkdown = (e) => {
  const selection: any = window.getSelection()
  let lastReplacedSpan: any = null

  const regex = /\{\{#([^#]+)#\}\}/g
  const walker = document.createTreeWalker(e.target, NodeFilter.SHOW_TEXT, null)

  while (walker.nextNode()) {
    const node: any = walker.currentNode
    const text: any = node.nodeValue

    if (regex.test(text)) {
      regex.lastIndex = 0
      const fragment = document.createDocumentFragment()
      let lastIndex = 0
      let match

      while ((match = regex.exec(text)) !== null) {
        if (match.index > lastIndex) {
          fragment.appendChild(
            document.createTextNode(text.substring(lastIndex, match.index)),
          )
        }
        const key = match[1]
        const varsValue = document.createElement('div')
        varsValue.setAttribute('contenteditable', 'false')
        varsValue.style.display = 'inline-block'
        const app = createApp(paramValue, {
          vars: state.optionsMap.get(key),
        })
        app.component('SvgIcon', SvgIcon)
        app.mount(varsValue)
        fragment.appendChild(varsValue)

        lastReplacedSpan = varsValue
        lastIndex = regex.lastIndex
      }

      if (lastIndex < text.length) {
        fragment.appendChild(document.createTextNode(text.substring(lastIndex)))
      }

      node.parentNode.replaceChild(fragment, node)
    }
  }

  if (lastReplacedSpan) {
    const newRange = document.createRange()
    newRange.setStartAfter(lastReplacedSpan)
    newRange.collapse(true)
    const newSelection: any = window.getSelection()
    newSelection.removeAllRanges()
    newSelection.addRange(newRange)
  }
  state.textCount = e.target.innerText?.length || 0
}
const handlePaste = (e) => {
  e.preventDefault()
  const text = (e.clipboardData || window.clipboardData).getData('text')
  document.execCommand('insertText', false, text)
}
const onCopy = (text) => {
  copy(text)
  ElMessage.success('复制成功！')
}
const setVars = (vars) => {
  console.log(vars)
}
onMounted(() => {})
</script>

<style scoped lang="scss"></style>
