<!-- 报告元数据，封面上的动态字段 -->
<script setup lang="ts">
import { defineAsyncComponent, ref, markRaw, type Ref, type PropType, onMounted } from "vue";
import { PlusOutlined, MinusCircleOutlined } from '@ant-design/icons-vue';
import draggable from 'vuedraggable'

import type ReportMetaTextInput from './ReportMetaTextInput.vue';
import type { ReportMetadataItem } from "@/types/report.types";

type ComponentType = typeof ReportMetaTextInput;

const props = defineProps({
  data: {
    type: Array as PropType<ReportMetadataItem[]>,
    required: true,
  }
});

interface DynamicComponent {
  id: number;
  component: ComponentType;
  prop: ReportMetadataItem;
}

const dynamicComponents: Ref<DynamicComponent[]> = ref([]);

const emits = defineEmits<{
  (e: "change", data: ReportMetadataItem[]): void;
}>();

function addTextComponent(index: number, prop: ReportMetadataItem = { name: '', value: '', type: 'text' }) {
  dynamicComponents.value.push({
    id: index,
    component: markRaw(defineAsyncComponent(() => import('./ReportMetaTextInput.vue') )),
    prop
  });
}

function addDateComponent(index: number, prop: ReportMetadataItem = { name: '', value: '', type: 'date' }) {
  dynamicComponents.value.push({
    id: index,
    component: markRaw(defineAsyncComponent(() => import('./ReportMetaDateInput.vue') )),
    prop
  });
}

function addDateRangeComponent(index: number, prop: ReportMetadataItem = { name: '', value: '', type: 'dateRange' }) {
  dynamicComponents.value.push({
    id: index,
    component: markRaw(defineAsyncComponent(() => import('./ReportMetaDateRangeInput.vue') )),
    prop
  });
}

function handleMenuClick(e: {key: string}) {
  const index = dynamicComponents.value.length+1;
  if (e.key == 'text') {
    addTextComponent(index);
  } else if (e.key === 'date') {
    addDateComponent(index);
  } else if (e.key === 'dateRange') {
    addDateRangeComponent(index,{ name: '起止时间', value: '', type: 'dateRange' });
  }
}

function emitChange() {
  const props = dynamicComponents.value.map((item) => item.prop);
  emits("change", props);
}

function deleteComponent(index: number) {
  dynamicComponents.value.splice(index, 1);
  emitChange()
}

function onMetaCompChange() {
  emitChange()
}

function onDragEnd() {
  emitChange()
}

onMounted(() => {
  if (props.data) {
    props.data.forEach((metadataItem, index) => {
      if (metadataItem.type == 'text') {
        addTextComponent(index, metadataItem);
      } else if (metadataItem.type == 'date') {
        addDateComponent(index, metadataItem);
      } else if (metadataItem.type == 'dateRange') {
        addDateRangeComponent(index, metadataItem);
      }
    })
  }
});
</script>

<template>
  <div class="dynamic-meta-wrap">
    <draggable v-model="dynamicComponents" item-key="id" group="components" @end="onDragEnd">
      <template #item="{element, index}">
        <a-row type="flex" class="dynamic-meta-item-row">
          <a-col flex="1">
            <component
              :is="element.component"
              v-model:data="element.prop"
              @update:data="onMetaCompChange"
            />
          </a-col>
          <a-col>
            <a-button type="text" @click="deleteComponent(index)">
              <template #icon><minus-circle-outlined /></template>
            </a-button>
          </a-col>
        </a-row>
      </template>
    </draggable>
    <a-dropdown class="add-item-dropdown">
      <template #overlay>
        <a-menu @click="handleMenuClick">
          <a-menu-item key="text">文本项</a-menu-item>
          <a-menu-item key="date">日期项</a-menu-item>
          <a-menu-item key="dateRange">起止时间</a-menu-item>
        </a-menu>
      </template>
      <a-button>
        <plus-outlined />
        添加新项
      </a-button>
    </a-dropdown>
  </div>
</template>

<style scoped lang="scss">
.dynamic-meta-wrap {
  .dynamic-meta-item-row {
    margin-top: 0.5em;
  }

  .add-item-dropdown {
    margin-top: 0.5em;
  }
}
</style>
