<template>
  <div class="editor-outline">
    <Tabs v-model:activeKey="activeKey" @change="handleChange">
      <TabPane key="outline" tab="大纲">
        <div v-if="outlineData[activeKey] && outlineData[activeKey].length > 0" class="editor-outline-list">
          <a v-for="item in outlineData[activeKey]" :key="`outline-${item.id}`" :href="`#${item.id}`" :class="`editor-outline-item editor-outline-item-${item.depth}`" :title="item.text">
            {{ item.text }}
          </a>
        </div>
        <Empty v-else :image="simpleImage" />
      </TabPane>
      <TabPane key="image" tab="图片">
        <ImagePreviewGroup v-if="outlineData[activeKey] && outlineData[activeKey].length > 0" class="editor-image-list">
          <Image v-for="(item, index) in outlineData[activeKey]" :key="`image-${index}`" :class="`editor-image-item`" :src="item.src" />
        </ImagePreviewGroup>
        <Empty v-else :image="simpleImage" />
      </TabPane>
      <TabPane key="video" tab="视频">
        <div v-if="outlineData[activeKey] && outlineData[activeKey].length > 0" class="editor-video-list">
          <video
            v-for="(item, index) in outlineData[activeKey]"
            :key="`video-${index}`"
            :class="`editor-video-item`"
            preload="metadata"
            :src="item.src"
            webkit-playsinline="webkit-playsinline"
            playsinline
            controls
          ></video>
        </div>
        <Empty v-else :image="simpleImage" />
      </TabPane>
      <TabPane key="audio" tab="音频">
        <div v-if="outlineData[activeKey] && outlineData[activeKey].length > 0" class="editor-audio-list">
          <audio
            v-for="(item, index) in outlineData[activeKey]"
            :key="`audio-${index}`"
            :class="`editor-audio-item`"
            preload="none"
            :src="item.src"
            webkit-playsinline="webkit-playsinline"
            playsinline
            controls
          ></audio>
        </div>
        <Empty v-else :image="simpleImage" />
      </TabPane>
    </Tabs>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref, reactive, PropType } from 'vue';
import { $, EngineInterface } from '@aomao/engine';
import { Outline, OutlineData } from '@aomao/plugin-heading';
import { throttle } from 'lodash';
import { Tabs, TabPane, Image, ImagePreviewGroup, Empty } from 'ant-design-vue';

const outline = new Outline();

export default defineComponent({
  name: 'am-outline',
  components: { Tabs, TabPane, Image, ImagePreviewGroup, Empty },
  props: {
    engine: { type: Object as PropType<EngineInterface>, required: true },
  },
  data() {
    return {
      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
    };
  },
  setup(props) {
    const { engine } = { ...props };
    const activeKey = ref<string>('outline');
    const outlineData = reactive<any>({
      outline: [],
      image: [],
      video: [],
      audio: [],
    });
    const readingSection = ref<number>(-1);
    onMounted(() => {
      handleChange();
      // 监听编辑器值改变事件
      engine.on('change', throttle(handleChange, 400));
    });

    const handleChange = () => {
      const toc = getTocData(engine, activeKey.value);
      outlineData[activeKey.value] = toc;
    };

    const getTocData = (editor: any, activeKey: string) => {
      const nodes: Array<Element> = [];
      const { card } = editor;
      switch (activeKey) {
        case 'outline':
          editor.container.find('h1,h2,h3,h4,h5,h6').each((child: any) => {
            const node = $(child);
            // Card 里的标题，不纳入大纲
            if (card.closest(node)) {
              return;
            }
            // 非一级深度标题，不纳入大纲
            if (!node.parent()?.isRoot()) {
              return;
            }
            nodes.push(node.get<Element>()!);
          });
          return outline.normalize(nodes);
        case 'image':
          editor.container.find('img').each((child: any) => {
            const node = $(child);
            // Card 里的图片
            if (card.closest(node) && node.parent()?.hasClass('data-image-meta')) {
              nodes.push(node.get<Element>()!);
            }
          });
          return nodes;
        case 'video':
          editor.container.find('video').each((child: any) => {
            const node = $(child);
            // Card 里的视频
            if (card.closest(node) && node.parent()?.hasClass('data-video-content')) {
              nodes.push(node.get<Element>()!);
            }
          });
          return nodes;
        case 'audio':
          editor.container.find('audio').each((child: any) => {
            const node = $(child);
            // Card 里的视频
            if (card.closest(node) && node.parent()?.hasClass('data-audio-content')) {
              nodes.push(node.get<Element>()!);
            }
          });
          return nodes;
        default:
          break;
      }
    };

    return {
      activeKey,
      outlineData,
      readingSection,
      handleChange,
    };
  },
});
</script>
<style>
.editor-outline {
  /* position: absolute;
  top: 0px;
  left: calc(100% + 10px); */
  width: 320px;
  height: auto;
  max-height: 100%;
  background: #fff;
  border: 1px solid #f0f0f0;
  padding: 16px;
}
.editor-outline-item {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: block;
  font-size: 12px;
  line-height: 20px;
  color: inherit;
}
.editor-outline .editor-outline-item-active,
.editor-outline .editor-outline-item:hover,
.editor-outline .editor-outline-item:focus {
  color: #1890ff;
  text-decoration: none;
}
.editor-outline .editor-outline-item-2 {
  padding-left: 16px;
}
.editor-outline .editor-outline-item-3 {
  padding-left: 32px;
}
.editor-outline .editor-outline-item-4 {
  padding-left: 48px;
}
.editor-outline .editor-outline-item-5 {
  padding-left: 64px;
}
.editor-outline .editor-outline-item-6 {
  padding-left: 80px;
}
.editor-video-list,
.editor-image-list,
.editor-audio-list {
  margin: -5px;
}
.editor-video-item,
.editor-image-item,
.editor-audio-item {
  width: 100%;
  padding: 5px;
}
</style>
