<template>
  <TMagicScrollbar class="m-editor-layer-panel">
    <slot name="layer-panel-header"></slot>

    <SearchInput @search="filterTextChangeHandler"></SearchInput>

    <Tree
      v-if="page && nodeStatusMap"
      tabindex="-1"
      ref="tree"
      :data="[page]"
      :node-status-map="nodeStatusMap"
      @node-dragover="handleDragOver"
      @node-dragstart="handleDragStart"
      @node-dragleave="handleDragLeave"
      @node-dragend="handleDragEnd"
      @node-contextmenu="nodeContentmenuHandler"
      @node-mouseenter="mouseenterHandler"
      @node-click="nodeClickHandler"
    >
      <template #tree-node-tool="{ data: nodeData }">
        <slot name="layer-node-tool" :data="nodeData">
          <LayerNodeTool :data="nodeData"></LayerNodeTool>
        </slot>
      </template>

      <template #tree-node-content="{ data: nodeData }">
        <slot name="layer-node-content" :data="nodeData"> </slot>
      </template>
    </Tree>

    <Teleport to="body">
      <LayerMenu ref="menu" :layer-content-menu="layerContentMenu" @collapse-all="collapseAllHandler"></LayerMenu>
    </Teleport>
  </TMagicScrollbar>
</template>

<script setup lang="ts">
import { computed, inject, ref } from 'vue';

import { TMagicScrollbar } from '@tmagic/design';

import SearchInput from '@editor/components/SearchInput.vue';
import Tree from '@editor/components/Tree.vue';
import { LayerPanelSlots, MenuButton, MenuComponent, Services } from '@editor/type';

import LayerMenu from './LayerMenu.vue';
import LayerNodeTool from './LayerNodeTool.vue';
import { useClick } from './use-click';
import { useDrag } from './use-drag';
import { useFilter } from './use-filter';
import { useKeybinding } from './use-keybinding';
import { useNodeStatus } from './use-node-status';

defineSlots<LayerPanelSlots>();

defineOptions({
  name: 'MEditorLayerPanel',
});

defineProps<{
  layerContentMenu: (MenuButton | MenuComponent)[];
}>();

const services = inject<Services>('services');
const editorService = services?.editorService;

const tree = ref<InstanceType<typeof Tree>>();

const page = computed(() => editorService?.get('page'));

const { nodeStatusMap } = useNodeStatus(services, page);
const { isCtrlKeyDown } = useKeybinding(services, tree);

const { filterTextChangeHandler } = useFilter(nodeStatusMap, page);

const collapseAllHandler = () => {
  if (!page.value || !nodeStatusMap.value) return;
  const items = nodeStatusMap.value.entries();
  for (const [id, status] of items) {
    if (id === page.value.id) {
      continue;
    }
    status.expand = false;
  }
};

const { handleDragStart, handleDragEnd, handleDragLeave, handleDragOver } = useDrag(services);

const {
  menu,
  nodeClickHandler,
  nodeContentmenuHandler,
  highlightHandler: mouseenterHandler,
} = useClick(services, isCtrlKeyDown, nodeStatusMap);
</script>
