<template>
  <div class="main-box">
    <PageToolbar class="mt1" />
    <div class="table-box">
      <div class="card h-flex flex-space-between pb0">
        <el-space>
          <yx-title>词表名称： {{ route.query.name }}</yx-title>
          <el-button v-auth="['wordLib:write']" type="primary" :icon="Plus" @click="addAction"> 新增 </el-button>
        </el-space>
        <el-space>
          <el-form-item label="标签来源：" style="margin-bottom: 0">
            <el-select v-model="filterPatams.wordSourceType" clearable>
              <el-option label="全部" :value="0"></el-option>
              <el-option label="新增/导入" :value="1"></el-option>
              <el-option label="标注" :value="2"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="标准词：" style="margin-bottom: 0">
            <el-input v-model="filterPatams.keyword" style="width: 300px" placeholder="请输入" clearable></el-input>
          </el-form-item>
        </el-space>
      </div>
      <ProTable
        ref="proTable"
        :columns="columns"
        :init-param="initParam"
        :search-col="{ xs: 1, sm: 1, md: 2, lg: 3, xl: 3 }"
        :pagination="false"
        :request-auto="false"
        :tool-button="false"
        :data="fitlerTableData"
        default-expand-all="false"
      >
        <!-- 序号 -->
        <template #index> </template>
        <!-- 标准词名称 -->
        <template #wordName="scope">
          <div class="h-flex">
            <div :style="{ width: `${(scope.row.level - 1) * 20}px` }"></div>
            <AutoSaveInput
              style="flex: 1"
              :ref="scope.row.id.toString()"
              :maxlength="50"
              :display-value="scope.row.wordName"
              @focus="editing = true"
              @done="editNameSave($event, scope.row)"
            >
              <template #suffix v-if="scope.row.wordSourceType === 2">
                <img
                  class="ml5"
                  style="vertical-align: middle"
                  src="@/assets/images/label_tag.png"
                  width="48"
                  height="20"
                  alt="标注"
                />
              </template>
            </AutoSaveInput>
          </div>
        </template>
        <!-- 表格操作 -->
        <template #operation="scope">
          <el-button type="primary" link :icon="View" :disabled="editing" @click="viewSynonymAction(scope.row)">
            查看同义词
          </el-button>
          <el-button
            v-auth="['wordLib:write']"
            type="primary"
            link
            :icon="EditPen"
            :disabled="editing"
            @click="editAction(scope.row)"
          >
            编辑
          </el-button>
          <el-button
            v-auth="['wordLib:write']"
            type="primary"
            link
            :icon="Delete"
            :disabled="editing"
            @click="delAction(scope.row)"
          >
            删除
          </el-button>
        </template>
      </ProTable>
    </div>
    <SynonymDialog ref="synonymRef" />
    <AddWordDialog ref="addWordRef" />
  </div>
</template>
<script setup lang="ts">
import { ref, reactive, getCurrentInstance, computed, provide } from "vue";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import { useHandleData } from "@/hooks/useHandleData";
import { usePageLeave } from "@/hooks/usePageLeave";
import ProTable from "@/components/ProTable/index.vue";
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface";
import { AnnoLexicon, WordLib } from "@/api/interface";
import { getTandardWordDetail, deleteTandardWord, editTandardWord } from "@/api/modules/annotation/lexicon";
import { View, Plus, Delete, EditPen } from "@element-plus/icons-vue";
import SynonymDialog from "./components/SynonymDialog.vue";
import AutoSaveInput from "./components/AutoSaveInput.vue";
import AddWordDialog from "./components/AddWordDialog.vue";

// hooks
usePageLeave("AnnoLexicon");

// router
const route = useRoute();
// ProTable 实例
const proTable = ref<ProTableInstance>();
const proxy: any = getCurrentInstance()?.proxy;

// ref
const synonymRef = ref<typeof SynonymDialog>();
const addWordRef = ref<typeof AddWordDialog>();
const editing = ref(false);
const filterPatams = ref({ keyword: "", wordSourceType: 0 });
const tableData = ref<AnnoLexicon.ResStandardDetail[]>([]);

// provide
provide("treeData", tableData);

// 如果表格需要初始化请求参数，直接定义传给 ProTable(之后每次请求都会自动带上该参数，此参数更改之后也会一直带上，改变此参数会自动刷新表格数据)
const initParam = reactive({});

const fitlerTableData = computed(() => {
  const { keyword, wordSourceType } = filterPatams.value;
  let result = tableData.value;
  if (keyword || wordSourceType) {
    result = filterTree(tableData.value, (node: { wordName: string; wordSourceType: number }) => {
      if (wordSourceType && node.wordSourceType !== wordSourceType) {
        return false;
      }
      return node.wordName.includes(keyword);
    });
  }
  return result.map((item, index) => ({ ...item, sortIndex: index + 1 }));
});

type TreeNode = AnnoLexicon.ResStandardDetail;
// 过滤树状列表数据
function filterTree(tree: TreeNode[], isMatchFn: any): TreeNode[] {
  return tree.reduce((result, node) => {
    const filteredNode: TreeNode = {
      ...node,
      children: []
    };

    if (node.children && node.children.length > 0) {
      const filteredChildren = filterTree(node.children, isMatchFn);
      if (filteredChildren.length > 0) {
        filteredNode.children = filteredChildren;
      }
    }

    if (
      isMatchFn(node) ||
      (node.children && node.children.length > 0 && filteredNode.children && filteredNode.children.length > 0)
    ) {
      result.push(filteredNode);
    }

    return result;
  }, [] as TreeNode[]);
}

// 表格配置项
const columns = reactive<ColumnProps<AnnoLexicon.ResStandardDetail>[]>([
  {
    prop: "index",
    label: "",
    align: "left",
    width: 120,
    showOverflowTooltip: false
  },
  { prop: "wordName", label: "标准词", align: "left" },
  { prop: "operation", label: "操作", width: 300, fixed: "right" }
]);

// 编辑名称失去焦点自动保存
async function editNameSave({ event, inputValue, displayValue, callback }: any, row: AnnoLexicon.ResStandardDetail) {
  if (inputValue.length === 0) {
    ElMessage.warning("标准词名称为空");
    event.target.focus();
    return;
  }
  if (inputValue !== displayValue) {
    try {
      await editTandardWord({ standardWordId: row.id, standardWordName: inputValue });
      editing.value = false;
      getTableList();
    } catch (err) {
      console.log(err);
      event.target.focus();
      return;
    }
  }
  editing.value = false;
  callback();
}

// 分页列表获取数据
const getTableList = async () => {
  if (editing.value) return;
  const res = await getTandardWordDetail({ id: Number(route.query.id) });
  tableData.value = res.data || [];
};
getTableList();

// 查看同义词
const viewSynonymAction = (row: AnnoLexicon.ResStandardDetail) => {
  const wordLink = findNodeAndParents(fitlerTableData.value, row.id);
  console.log(wordLink.map(item => item.wordName));
  synonymRef.value?.open({ id: row.id, wordLink });
};

// 查找节点及其父级
function findNodeAndParents(tree: AnnoLexicon.ResStandardDetail[], targetId: number): WordLib.Standard[] | [] {
  for (const node of tree) {
    if (node.id === targetId) {
      return [node];
    }

    if (node.children && node.children.length > 0) {
      const result = findNodeAndParents(node.children, targetId);
      if (result.length > 0) {
        return [node, ...result];
      }
    }
  }

  // If the target is not found in the current subtree, return null
  return [];
}

// 新增
const addAction = () => {
  addWordRef.value?.open().then(() => {
    getTableList();
  });
};

// 编辑
const editAction = (row: AnnoLexicon.ResStandardDetail) => {
  proxy?.$refs[row.id].startEditing();
};

// 删除
const delAction = async (row: AnnoLexicon.ResStandardDetail) => {
  await useHandleData(deleteTandardWord, { id: row.id }, `是否删除当前词语，删除后该词语关联关系取消！`);
  getTableList();
};
</script>

<style lang="scss" scoped>
.main-box {
  height: 100%;
  padding: 0;
  .table-box {
    box-sizing: border-box;
    flex: 1;
    height: 0;
    padding: 10px;
  }
}
</style>
