<template>
    <NElement
        tag="div"
        class="et-outline m-4 p-2 rounded-lg border outline-none text-left overflow-auto"
        @keydown="onKeyDown"
        @keypress="onKeyPressed"
        @keyup="onKeyUp"
        contenteditable
        style="width: 200px; height: 300px"
        ref="el"
    >
        <p data-level="0" data-title="第一章"></p>
    </NElement>
</template>
<script setup lang="ts">
import { Ref, computed, onMounted, reactive, ref, watch, defineEmits } from 'vue'
import { useMutationObserver, useDebounceFn } from '@vueuse/core'
import { NConfigProvider, NElement, useThemeVars } from 'naive-ui'
// @ts-ignore
import * as NumberToChinese from '@siakhooi/number-to-chinese-words'

const props = defineProps({
    modelValue: {
        type: Array<any>,
        default: (): any[] => []
    }
})
watch(props.modelValue, v => {
    if (JSON.stringify(v) !== JSON.stringify(props.modelValue)) {
        update(props.modelValue)
    }
})
const themeVars = useThemeVars()
const el: Ref<any> = ref(null)
const et = computed(() => {
    return el.value?.$el as HTMLElement
})

onMounted(() => {
    useMutationObserver(
        et.value,
        mutations => {
            if (mutations.flatMap(m => Array.from(m.addedNodes).concat(Array.from(m.removedNodes))).length > 0) {
                arrange()
            } else if (mutations.filter(m => m.type === 'characterData').length > 0) {
                arrange()
            }
            // arrange()
        },
        {
            attributes: true,
            childList: true,
            subtree: true,
            characterData: true
        }
    )
    update(props.modelValue)
})

const chapters: any[] = reactive([])

const emit = defineEmits(['update:modelValue'])
watch(chapters, v => {
    emit('update:modelValue', v)
})
const arrange = useDebounceFn(() => {
    const levels = [0, 0, 0, 0]
    chapters.splice(0, chapters.length)
    for (const child of Array.from(et.value?.children || [])) {
        const e = child as Element
        const level = parseInt(e.getAttribute('data-level') || '0')
        levels[level] = levels[level] + 1
        for (let i = level + 1; i < levels.length; i++) {
            levels[i] = 0
        }
        if (level === 0) {
            e.setAttribute(
                'data-title',
                '第' + NumberToChinese.convertNumber(levels[0], { removeLeadingOne: levels[level] > 1 }) + '章'
            )
        } else {
            e.setAttribute('data-title', levels.slice(0, level + 1).join('.'))
        }

        let node: any
        let parent = chapters
        levels.slice(0, level + 1).forEach((v: number) => {
            node = parent[v - 1]
            if (!node) {
                node = {
                    children: []
                }
                parent[v - 1] = node
            }
            parent = node.children
        })
        if (node) node.title = e.textContent
    }
}, 10)

function update(chaptersData: any) {
    console.log('update')
    chaptersData = chaptersData || []
    const list: any[] = []
    function _update(_data: any, level: number) {
        _data.forEach((e: any) => {
            list.push({
                title: e.title,
                level
            })
            _update(e.children, level + 1)
        })
    }
    _update(chaptersData, 0)
    et.value?.childNodes.forEach((e: any) => {
        et.value?.removeChild(e)
    })
    list.forEach((e, i) => {
        const p = document.createElement('p')
        p.setAttribute('data-level', e.level.toString())
        p.textContent = e.title
        et.value?.appendChild(p)
    })
    arrange()
    console.log(list)
}

function onKeyDown(e: KeyboardEvent) {
    const sel = window.getSelection()!
    let node = sel!.anchorNode!
    if (node?.nodeName !== 'P') {
        node = node.parentNode!
    }
    const idx = Array.from(node?.parentNode?.children || []).indexOf(node as any)

    if (e.key === 'Enter') {
        if (e.shiftKey) {
            e.preventDefault()
            return
        }
        // e.preventDefault()
        // const p = document.createElement('p')
        // et.value?.insertBefore(p, node!.parentNode!.children[idx + 1])
        // let prev
        // if (idx === 0) {
        //     prev = node
        // } else {
        //     prev = node!.parentNode!.children[idx - 1]
        // }
        // p.setAttribute('data-title', '第二章')
        // p.setAttribute('data-level', (prev as Element)?.getAttribute('data-level') || '0')
        // range.setStart(p, 0)
        // range.collapse(true)
        // sel?.removeAllRanges()
        // sel?.addRange(range)
    } else if (e.key === 'Tab') {
        e.preventDefault()
        if (idx === 0) return
        let level = parseInt((node as Element).getAttribute('data-level') || '0')
        level += e.shiftKey ? -1 : 1
        level = Math.min(Math.max(0, level), 3)
        ;(node as Element).setAttribute('data-level', level.toString())
        arrange()
        console.log(e)
    } else if (e.key === 'Backspace') {
        if (!node.textContent && node.parentNode?.children.length === 1) {
            e.preventDefault()
        }
        //
    }
}
function onKeyPressed(e: KeyboardEvent) {}
function onKeyUp(e: KeyboardEvent) {}
</script>
<style lang="less" scoped>
.et-outline {
    &:focus {
        border-color: var(--primary-color);
    }
    :deep(p) {
        &::before {
            content: attr(data-title) ' ';
            opacity: 0.6;
        }
        &[data-level='1'] {
            padding-left: 16px;
        }
        &[data-level='2'] {
            padding-left: 32px;
        }
        &[data-level='3'] {
            padding-left: 48px;
        }
    }
}
</style>
