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

    type Lang = 'zh_CN' | 'en_US' | 'ja_JP' | 'ko_KR' | undefined
    export default defineComponent({
        inheritAttrs: false,
        props: {
            height: { type: Number, default: 360 },
            value: { type: String, default: '' },
        },
        emits: ['change', 'get', 'update:value'],
        setup(props, { attrs, emit }) {
            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 || '')
            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,
                    },
                })
            }
            const instance = {
                getVditor: (): Vditor => vditorRef.value!,
            }
            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)
            return {
                wrapRef,
                ...instance,
            }
        },
    })
</script>

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