<script lang="ts" setup>
import type { Ref } from 'vue'
import { computed, nextTick, onBeforeUnmount, onDeactivated, ref, unref, useAttrs, watch } from 'vue'
import Vditor from 'vditor'
import 'vditor/dist/index.css'
import { useModalContext } from '../../Modal'
import { getTheme } from './getTheme'
import { useLocale } from '@/locales/useLocale'
import { useRootSetting } from '@/hooks/setting/useRootSetting'
import { onMountedOrActivated } from '@/hooks/core/onMountedOrActivated'
import { propTypes } from '@/utils/propTypes'

defineOptions({ inheritAttrs: false })

const props = defineProps({
  height: propTypes.number.def(360),
  value: propTypes.string.def(''),
})

const emit = defineEmits(['change', 'get', 'update:value'])

type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined

const attrs = useAttrs()
const wrapRef = ref<ElRef>(null)
const vditorRef = ref(null) as Ref<Nullable<Vditor>>
const initedRef = ref(false)

const modalFn = useModalContext()

const { getLocale } = useLocale()
const { getDarkMode } = useRootSetting()
const valueRef = ref(props.value || '')

const instance = {
  getVditor: (): Vditor => vditorRef.value!,
}

watch(
  [() => getDarkMode.value, () => initedRef.value],
  ([val, inited]) => {
    if (!inited)
      return

    instance.getVditor()?.setTheme(getTheme(val) as any, getTheme(val, 'content'), getTheme(val, 'code'))
  },
  {
    immediate: true,
    flush: 'post',
  },
)

watch(
  () => props.value,
  (v) => {
    if (v !== valueRef.value)
      instance.getVditor()?.setValue(v)

    valueRef.value = v
  },
)

const getCurrentLang = computed((): 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' => {
  let lang: Lang
  switch (unref(getLocale)) {
    case 'en':
      lang = 'en_US'
      break
    case 'ja':
      lang = 'ja_JP'
      break
    case 'ko':
      lang = 'ko_KR'
      break
    default:
      lang = 'zh_CN'
  }
  return lang
})
function init() {
  const wrapEl = unref(wrapRef) as HTMLElement
  if (!wrapEl)
    return
  const bindValue = { ...attrs, ...props }
  const insEditor = new Vditor(wrapEl, {
    // 设置外观主题
    theme: getTheme(getDarkMode.value) as any,
    lang: unref(getCurrentLang),
    mode: 'sv',
    fullscreen: {
      index: 520,
    },
    preview: {
      theme: {
        // 设置内容主题
        current: getTheme(getDarkMode.value, 'content'),
      },
      hljs: {
        // 设置代码块主题
        style: getTheme(getDarkMode.value, 'code'),
      },
      actions: [],
    },
    input: (v) => {
      valueRef.value = v
      emit('update:value', v)
      emit('change', v)
    },
    after: () => {
      nextTick(() => {
        modalFn?.redoModalHeight?.()
        insEditor.setValue(valueRef.value)
        vditorRef.value = insEditor
        initedRef.value = true
        emit('get', instance)
      })
    },
    blur: () => {
      // unref(vditorRef)?.setValue(props.value);
    },
    ...bindValue,
    cache: {
      enable: false,
    },
  })
}

function destroy() {
  const vditorInstance = unref(vditorRef)
  if (!vditorInstance)
    return
  try {
    vditorInstance?.destroy?.()
  }
  catch (error) {}
  vditorRef.value = null
  initedRef.value = false
}

onMountedOrActivated(init)

onBeforeUnmount(destroy)
onDeactivated(destroy)
</script>

<template>
  <div ref="wrapRef" />
</template>
