<template>
  <div class="group-tag-list">
    <div>
      <el-button v-if="BUTTONS.import" :icon="Upload" type="primary" :disabled="editing" @click="importAction"> 导入 </el-button>
      <el-button v-if="BUTTONS.export" :icon="Download" type="primary" plain :disabled="editing" @click="exportAction">
        导出
      </el-button>
    </div>
    <div class="add-group mt40 mb20" v-if="BUTTONS.add">
      <el-button :icon="Plus" type="primary" @click="addGroup" :disabled="editing"> 添加分组 </el-button>
    </div>
    <div ref="scrollRef" class="scroll-box scroll-y">
      <TransitionGroup name="list" tag="div">
        <div class="group-item mb10" v-for="(item, index) in groupList" :key="item.id">
          <svg-icon name="groupname" :icon-style="{ width: '28px', height: '28px' }" />
          <div class="group-name ml10">
            <DblclickInput
              :ref="item.id.toString()"
              :maxlength="20"
              type="textarea"
              resize="none"
              autosize
              :display-value="item.name"
              :disabled="!BUTTONS.edit || !item.editableFlag"
              @focus="editing = true"
              @done="groupNameInputDone($event, item)"
            />
          </div>
          <div class="divider mr20 ml20"></div>
          <el-space :size="[20, 10]" wrap>
            <el-tag
              v-for="tag in item.children"
              :key="tag.id"
              size="large"
              @close="removeTag(tag)"
              :closable="BUTTONS.delete && tag.editableFlag"
            >
              <DblclickInput
                v-if="BUTTONS.edit && tag.editableFlag"
                :maxlength="20"
                :display-value="tag.name"
                @focus="editing = true"
                @done="tagNameInputDone($event, item, tag)"
              />
              <template v-else>
                {{ tag.name }}
              </template>
            </el-tag>
            <!-- <el-input v-model="input1" placeholder="添加标签"> </el-input> -->
            <el-button class="add-tag-btn" :disabled="editing" v-if="BUTTONS.add">
              <DblclickInput
                :maxlength="20"
                :disabled="editing"
                display-value=""
                :is-dblclick="false"
                @focus="editing = true"
                @done="tagNameInputDone($event, item)"
              >
                添加标签
              </DblclickInput>
            </el-button>
          </el-space>
          <el-button
            v-if="item.editableFlag && BUTTONS.delete"
            class="del-btn ml20"
            link
            @click="removeGroup(item, index)"
            :disabled="editing && !item.isNew"
          >
            删除
          </el-button>
        </div>
      </TransitionGroup>
    </div>

    <ImportExcelDialog
      ref="importRef"
      :file-size="50"
      :title="isAttr ? '条文属性' : '命名标签'"
      :temp-path="isAttr ? './excel/attr_temp.xlsx' : './excel/tag_temp.xlsx'"
      :api="isAttr ? importAttr : importTag"
    />
  </div>
</template>

<script lang="ts" setup>
import { ref, nextTick, getCurrentInstance, defineExpose, defineProps } from "vue";
import { ElMessage, ElScrollbar } from "element-plus";
import { Plus, Upload, Download } from "@element-plus/icons-vue";
import { useHandleData } from "@/hooks/useHandleData";
import { useDownload } from "@/hooks/useDownload";
import { useAuthButtons } from "@/hooks/useAuthButtons";
import { AnnoTag } from "@/api/interface";
import {
  getAttrTreeList,
  getTagTreeList,
  addAttr,
  addTag,
  editAttr,
  editTag,
  deleteAttr,
  deleteTag,
  importTag,
  importAttr,
  exportTag,
  exporAttr
} from "@/api/modules/annotation/tag";
import ImportExcelDialog from "@/components/ImportExcelDialog/index.vue";
import DblclickInput from "./DblclickInput.vue";

// prop
const props = defineProps({
  isAttr: {
    type: Boolean,
    default: false
  }
});

// hooks
const { BUTTONS } = useAuthButtons({
  import: ["tag:exportOrImport"],
  export: ["tag:exportOrImport"],
  add: ["tag:write"],
  edit: ["tag:write"],
  delete: ["tag:write"]
});

// ref
const proxy = getCurrentInstance()?.proxy;
const editing = ref(false);
const importRef = ref<typeof ImportExcelDialog>();
const scrollRef = ref<typeof ElScrollbar>();
const groupList = ref<AnnoTag.ResTagTreeList[]>([]);

// 获取列表数据
async function getDataList() {
  const api = props.isAttr ? getAttrTreeList : getTagTreeList;
  const res = await api();
  groupList.value = res.data;
}
getDataList();

// 导入
function importAction() {
  importRef.value?.open().then(getDataList);
}

// 导出
async function exportAction() {
  await useDownload(props.isAttr ? exporAttr : exportTag, props.isAttr ? "导出条文属性" : "导出命名标签", {}, true, ".xlsx");
}

// 添加分组
function addGroup() {
  const id = Date.now();
  groupList.value.push({
    id,
    name: "",
    parentId: 0,
    children: [],
    editableFlag: true,
    isNew: true
  });
  nextTick(() => {
    // 输入框自动获取焦点
    (proxy?.$refs[id] as typeof DblclickInput)[0].startEditing();
    scrollToBottom();
  });
}

// 分组名编辑
async function groupNameInputDone({ event, inputValue, displayValue, callback }: any, item: AnnoTag.ResTagTreeList) {
  if (inputValue.length === 0) {
    ElMessage.warning("标签分组名称不可为空");
    event.target.focus();
    return;
  }
  if (inputValue !== displayValue) {
    const addApi = props.isAttr ? addAttr : addTag;
    const editApi = props.isAttr ? editAttr : editTag;
    try {
      if (item.isNew) {
        // 新增
        await addApi({ parentId: item.parentId, name: inputValue });
        ElMessage.success("新增成功");
      } else {
        // 编辑
        await editApi({ id: item.id, name: inputValue });
        ElMessage.success("保存成功");
      }
      getDataList();
    } catch (err) {
      console.log(err);
      event.target.focus();
      return;
    }
  }
  editing.value = false;
  callback();
}

// 标签名编辑
async function tagNameInputDone(
  { event, inputValue, displayValue, callback }: any,
  item: AnnoTag.ResTagTreeList,
  tag?: AnnoTag.TagItem
) {
  if (inputValue.length === 0) {
    if (!tag) {
      editing.value = false;
      callback();
      return;
    }
    ElMessage.warning("标签名称不可为空");
    event.target.focus();
    return;
  }
  if (inputValue !== displayValue) {
    const addApi = props.isAttr ? addAttr : addTag;
    const editApi = props.isAttr ? editAttr : editTag;
    try {
      if (tag) {
        // 编辑
        await editApi({ id: tag.id, name: inputValue });
        ElMessage.warning("保存成功");
      } else {
        // 新增
        await addApi({ parentId: item.id, name: inputValue });
        ElMessage.warning("新增成功");
      }
      getDataList();
    } catch (err) {
      console.log(err);
      event.target.focus();
      return;
    }
  }
  editing.value = false;
  callback();
}

// 移除标签
async function removeTag(tag: AnnoTag.TagItem) {
  if (editing.value) return;
  await useHandleData(
    props.isAttr ? deleteAttr : deleteTag,
    { id: tag.id },
    `确认删除当前标签，删除后数据标注时将无法使用当前标签进行标注！`
  );
  getDataList();
}

// 移除分组
async function removeGroup(item: AnnoTag.ResTagTreeList, index: number) {
  if (item.isNew) {
    groupList.value.splice(index, 1);
    editing.value = false;
    return;
  }
  await useHandleData(
    props.isAttr ? deleteAttr : deleteTag,
    { id: item.id },
    `确认删除当前标签分组，删除后数据标注时将无法使用当前标签分组进行标注！`
  );
  getDataList();
}

// 滚动到底部
function scrollToBottom() {
  if (scrollRef.value) {
    scrollRef.value.scrollTop = scrollRef.value?.scrollHeight;
  }
}

defineExpose({
  getDataList,
  editing
});
</script>

<style lang="scss" scoped>
.group-tag-list {
  display: flex;
  flex-direction: column;
  height: 100%;
  .scroll-box {
    flex: 1;
    height: 0;
  }
  .group-item {
    display: flex;
    align-items: center;
    padding: 20px;
    background: #f5f7fa;
    border-radius: 2px;
    .group-name {
      width: 120px;
      font-size: 16px;
      line-height: 24px;
      color: #333333;
      overflow-wrap: break-word;
    }
    .divider {
      width: 2px;
      height: 40px;
      background: #dbdde0;
      border-radius: 1px;
    }
    .el-space {
      flex: 1;
      .el-input {
        :deep(.el-input__wrapper) {
          width: 100px;
        }
      }
    }
    .el-tag--large {
      height: 28px;
      font-size: 16px;
      border-color: #ba7d45;
    }
    .add-tag-btn {
      height: 28px;
      padding: 0 10px;
      font-size: 16px;
      font-weight: normal;
      color: #999999;
    }
    .del-btn {
      font-size: 16px;
      color: #999999;
    }
  }
}
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(50px);
}
</style>
