<template>
  <div class="vtj-setting-panel vtj-events">
    <SubPanel title="组件事件">
      <DataItem
        v-for="item in componentEventList"
        :title="item.name"
        :active="!!item.event"
        :removable="!!item.event"
        editable
        clickable
        @click="openBinder(item)"
        @edit="openBinder(item)"
        @remove="onUnbindEvent(item.name)"></DataItem>
      <ElEmpty
        v-if="componentEventList.length === 0"
        :image-size="50"
        description="该组件无自带事件"></ElEmpty>
    </SubPanel>
    <SubPanel title="鼠标事件">
      <DataItem
        v-for="item in mouseEventList"
        :title="item.name"
        :active="!!item.event"
        :removable="!!item.event"
        editable
        clickable
        @click="openBinder(item)"
        @edit="openBinder(item)"
        @remove="onUnbindEvent(item.name)"></DataItem>
    </SubPanel>
    <SubPanel title="键盘事件">
      <DataItem
        v-for="item in keyboardEventList"
        :title="item.name"
        :active="!!item.event"
        :removable="!!item.event"
        editable
        clickable
        @click="openBinder(item)"
        @edit="openBinder(item)"
        @remove="onUnbindEvent(item.name)"></DataItem>
    </SubPanel>
    <EventBinder
      v-if="binderVisible"
      v-model="binderVisible"
      :node="node"
      :eventItem="currentEvent"
      @submit="onSubmit"
      @cancel="closeBinder"
      @remove="onUnbindEvent"></EventBinder>
  </div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import {
  SubPanel,
  DataItem,
  MOUSE_EVENT_LIST,
  KEYBOARD_EVENT_LIST,
  Event,
  INode
} from '@vtj/engine';
import { useSelected } from '../hooks/useDesigner';
import useCore from '../hooks/useCore';
import { ElEmpty } from 'element-plus';
import EventBinder from '../binders/EventBinder.vue';

export interface EventItem {
  name: string;
  event: Event;
}

const { engine } = useCore();
const { selected } = useSelected();

const node = computed<INode>(() => {
  return selected.value?.node as INode;
});

const currentEvent = ref();
const binderVisible = ref(false);

const mouseEventList = computed<EventItem[]>(() => {
  const events: Record<string, Event> = node.value?.events || {};
  return MOUSE_EVENT_LIST.map((name) => {
    return {
      name,
      event: events[name]
    };
  });
});

const keyboardEventList = computed<EventItem[]>(() => {
  const events: Record<string, Event> = node.value?.events || {};
  return KEYBOARD_EVENT_LIST.map((name) => {
    return {
      name,
      event: events[name]
    };
  });
});

const componentEventList = computed<EventItem[]>(() => {
  if (!node.value) return [];
  const nodeName = node.value.name;
  const events: Record<string, Event> = node.value?.events || {};
  const desc = engine.assets.componentMap[nodeName];
  if (!desc || !desc.events) return [];

  return desc.events.map((item) => {
    const name = typeof item === 'string' ? item : item.name;
    return {
      name: name,
      event: events[name]
    };
  });
});

const openBinder = (item: any) => {
  currentEvent.value = item;
  binderVisible.value = true;
};

const closeBinder = () => {
  currentEvent.value = null;
  binderVisible.value = false;
};

const onSubmit = (item: EventItem) => {
  node.value.bindEvent(item.name, item?.event);
  closeBinder();
};

const onUnbindEvent = (name: string) => {
  node.value.unbindEvent(name);
  closeBinder();
};
</script>
