<template>
  <div class="gl-page-content-grey-full">
    <div class="content">
      <FileTree
        ref="fileTreeRef"
        :api="dataListDirKnowledgeApi"
        :params="{ dirType: DIR_TYPE.KNOWLEDGE }"
        @choseNode="choseNodeFun"
        @updateNav="updateNavFun"
      >
        <template #options>
          <el-button :icon="Plus" class="options" type="primary" @click="appendFun({})">
            {{ $t('知识库.新增') }}
          </el-button>
        </template>
        <template #treeAction="{ data }">
          <el-tooltip
            v-if="parsePermission(data.permissionValue).write"
            :content="$t('知识库.新增子目录')"
            placement="top"
          >
            <el-button type="primary" link @click.stop="appendFun(data)">
              <el-icon>
                <FolderAdd />
              </el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip
            v-if="parsePermission(data.permissionValue).write"
            :content="$t('通用.编辑')"
            placement="top"
          >
            <el-button type="primary" link @click.stop="updateFun(data)">
              <el-icon>
                <EditPen />
              </el-icon>
            </el-button>
          </el-tooltip>
          <el-tooltip
            v-if="parsePermission(data.permissionValue).delete"
            :content="$t('通用.删除')"
            placement="top"
          >
            <el-button type="danger" link @click.stop="confirmRemoveFun(data)">
              <el-icon>
                <Delete />
              </el-icon>
            </el-button>
          </el-tooltip>
        </template>
        <template #table>
          <div class="right-table">
            <div class="search">
              <TableSearch
                v-if="searchItems.length > 0"
                ref="tableSearchRef"
                :searchItems="searchItems"
                @search="searchFun"
                @reset="resetFun"
              />
            </div>
            <div class="table">
              <BaseTable
                ref="baseTableRef"
                :tableName="TABLE_NAME.SIMULATION_KNOWLEDGE"
                :api="apiName"
                :params="searchParams"
                showIndex
                :actionList="actionList"
                :exportApi="dataExportKnowledgeListApi"
                :showExport="parsePermission(currentFolder?.permissionValue).export"
                fullHeight
                :exportFileName="$t('知识库.知识库列表')"
                :exportParams="{
                  ...searchParams,
                  parentDirId: currentFolder?.id || '',
                }"
                @cell-dblclick="onCellDblclickFun"
              >
                <template #leftOptions>
                  <div>
                    <el-button
                      :icon="DArrowLeft"
                      @click="backFun"
                      :disabled="navList.length <= 1"
                      >{{ $t('通用.返回上一级') }}</el-button
                    >
                    <el-button
                      v-if="folderPermission.import"
                      type="primary"
                      :icon="Plus"
                      @click="openModalFun"
                      :disabled="!currentFolder"
                    >
                      {{ $t('知识库.上传') }}
                    </el-button>
                    <el-button @click="infoVisible = true" :disabled="!currentFolder">
                      {{ $t('知识库.基本信息') }}
                    </el-button>
                  </div>
                </template>
                <template #originalName="{ row }">
                  <el-icon v-if="row.dataType === 1">
                    <Folder />
                  </el-icon>
                  <el-icon v-else>
                    <Document />
                  </el-icon>
                  {{ row.originalName }}
                </template>
                <template #fileSize="{ row }">
                  {{ formatFileSize(row.fileSize) }}
                </template>
                <template #versionNo="{ row }">
                  {{ row.versionNo ? 'V' + row.versionNo : '--' }}
                </template>
                <template #poolInfos="{ row }">
                  <PoolTaskSelect :modelValue="row.poolInfos" :editable="false" />
                </template>
                <template #approvalStatus="{ row, column }">
                  <el-button
                    type="primary"
                    link
                    @click="openProcessFun(row)"
                    v-if="row[column.field] === 'pending'"
                  >
                    {{ KNOWLEDGE_APPROVE_STATUS.O[row[column.field]] }}
                  </el-button>
                  <el-button type="primary" link @click="openProcessFun(row)" v-else>
                    {{ $t('知识库.审批完成') }}
                  </el-button>
                </template>
                <template #approveType="{ row, column }">
                  <el-button
                    v-if="row.dataType === 2"
                    type="primary"
                    link
                    @click="openProcessFun(row)"
                  >
                    {{ KNOWLEDGE_APPROVE_TYPE.O[row[column.field]] }}</el-button
                  >
                </template>
              </BaseTable>
            </div>
          </div>
        </template>
      </FileTree>
    </div>
    <ApprovalProcess v-model="processVisible" :flowId="currentRow?.cidFlowId" />
    <KnowledgeDetailModal
      v-model="visible"
      :detail="currentRow"
      :folder="currentFolder"
      :tableName="TABLE_NAME.SIMULATION_KNOWLEDGE"
      :confirmLoading="confirmLoading"
      @confirm="onConfirmFun"
    />
    <FolderModal
      v-model="folderModalVisible"
      :detail="currentFolder"
      :mode="currentFolderMode"
      :confirmLoading="folderConfirmLoading"
      @confirm="onFolderConfirmFun"
    />
    <FilePreview v-model="previewVisible" :fileId="currentRow?.id" />
    <ApproveDel
      v-model="approveDelVisible"
      :api="dataDelFileApi"
      :params="approveDelParams"
      @confirm="refreshTableFun"
    />
    <!-- 删除文件夹审批 -->
    <ApproveDel
      v-model="approveDelDirVisible"
      :api="dataDelDirApi"
      :params="approveDelDirParams"
      @confirm="onDelDirConfirmFun"
    />
    <InfoDrawer v-model="infoVisible" :data="currentFolder" />
  </div>
</template>

<script lang="ts" setup>
import { computed, ref, watchEffect, type Ref } from 'vue';
import { DArrowLeft, Plus } from '@element-plus/icons-vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import FileTree from '@/components/common/fileTree/index.vue';
import KnowledgeDetailModal from './components/knowledgeDetailModal.vue';
import FolderModal from './components/folderDetailModal.vue';
import InfoDrawer from './components/infoDrawer.vue';
import {
  dataCreateDirApi,
  dataListDirApi,
  dataRenameDirApi,
  dataDelDirApi,
  dataQueryDirApi,
  dataFileSearchApi,
  dataDelFileApi,
  dataUpdateFileApi,
  batchAddFileInfoApi,
  dataExportKnowledgeListApi,
  isDirEmptyApi,
} from '@/api/data/data';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { RenderContentContext } from 'element-plus';
import { formatFileSize } from '@/utils/file';
import TableSearch from '@/components/common/table/tableSearch.vue';
import { cloneDeep } from 'lodash-es';
import { DIR_TYPE } from '@/utils/enum/data.ts';
import ApproveDel from '@/components/common/approveDel/index.vue';
import { useDict } from '@/utils/useDict';
import ApprovalProcess from '@/components/common/approvalProcess/index.vue';
import { useI18n } from 'vue-i18n';
import FilePreview from '@/components/common/filePreview/index.vue';
import emitter from '@/utils/eventBus';
import { TABLE_NAME } from '@/utils/enum/tableName';
import { downloadFileById } from '@/utils/file';
import PoolTaskSelect from '@/components/pool/poolTaskSelect.vue';
import { parsePermission } from '@/utils/permission';

const dataListDirKnowledgeApi = (params: any) => {
  return dataListDirApi({ ...params, dirType: DIR_TYPE.KNOWLEDGE });
};

const folderPermission = computed(() =>
  parsePermission(currentFolder.value?.permissionValue ?? 31)
);
const { t } = useI18n();
const { KNOWLEDGE_APPROVE_STATUS, KNOWLEDGE_APPROVE_TYPE } = useDict(
  'KNOWLEDGE_APPROVE_STATUS',
  'KNOWLEDGE_APPROVE_TYPE'
);
type Data = RenderContentContext['data'];
const fileTreeRef = ref<any>();
const baseTableRef = ref<any>();
const navList = ref<any>([]);
const currentFolder = ref();
const memoryFolder = ref();
const currentFolderMode: Ref<'add' | 'edit'> = ref('add');
const choseNodeFun = (data: Data) => {
  isSearching.value = false;
  currentFolder.value = data;
  memoryFolder.value = currentFolder.value;
};

const updateNavFun = (data: any) => {
  navList.value = data;
};

const backFun = () => {
  fileTreeRef.value.backFun();
};

const searchItems = computed(() => [
  { title: t('通用.名称'), key: 'fileName', inputMode: 'input' },
  {
    title: t('知识库.上传人'),
    key: 'uploadUserId',
    inputMode: 'userSelectMultiple',
  },
]);
const folderModalVisible = ref(false);
const folderConfirmLoading = ref(false);
const appendFun = (data: Data) => {
  currentFolder.value = data;
  currentFolderMode.value = 'add';
  folderModalVisible.value = true;
};
const updateFun = (data: Data) => {
  currentFolder.value = data;
  currentFolderMode.value = 'edit';
  folderModalVisible.value = true;
};
const confirmRemoveFun = async (data: Data) => {
  const res: any = await isDirEmptyApi({ dirId: data.id });
  if (res.code !== 200) {
    return;
  }
  if (res.data) {
    ElMessageBox.confirm(t('知识库.确认删除空目录'), t('通用.提示'), {
      confirmButtonText: t('通用.确定'),
      cancelButtonText: t('通用.取消'),
      type: 'warning',
    })
      .then(async () => {
        const delRes: any = await dataDelDirApi({ delDirId: data.id });
        if (delRes.code === 200) {
          refreshTreeAfterModifyOrRemove(data);
          ElMessage.success(delRes.message);
        }
      })
      .catch(() => {});
  } else {
    ElMessageBox.confirm(t('知识库.目录内文件将一同被删除'), t('通用.提示'), {
      confirmButtonText: t('通用.确定'),
      cancelButtonText: t('通用.取消'),
      type: 'warning',
    })
      .then(() => {
        currentFolderToDelete.value = data;
        approveDelDirParams.value = { delDirId: data.id };
        approveDelDirVisible.value = true;
      })
      .catch(() => {});
  }
};
const refreshTreeRoot = () => {
  fileTreeRef.value?.reloadFun();
  baseTableRef.value?.resetFun();
};
const refreshTreeOpenDir = (dirId: number) => {
  fileTreeRef.value?.openDirFun(dirId);
  baseTableRef.value?.resetFun();
};
const refreshTreeAfterAdd = (parentNode?: any | null) => {
  if (parentNode && typeof parentNode.id === 'number') {
    refreshTreeOpenDir(parentNode.id);
  } else {
    refreshTreeRoot();
  }
};
const isTopLevel = (node: any) => {
  if (!node || !node.objectKey) return false;
  const key = String(node.objectKey).replace(/\/$/, '');
  const parts = key.split('/');
  return parts.length === 2;
};
const refreshTreeAfterModifyOrRemove = (node?: any | null) => {
  if (isTopLevel(node)) {
    refreshTreeRoot();
  } else {
    refreshTreeOpenDir(node.parentId);
  }
};
const isSearching = ref(false);
const searchParams = ref<any>({
  fileId: currentFolder.value?.id || '',
  dirType: DIR_TYPE.KNOWLEDGE,
});

const actionList = computed(() => {
  return [
    {
      title: t('通用.预览'),
      type: 'primary',
      click: (row: any) => {
        previewFileFun(row);
      },
      hide: (row: any) => {
        return row.dataType !== 2 || !parsePermission(row.permissionValue).read;
      },
    },
    {
      title: t('通用.下载'),
      type: 'primary',
      click: (row: any) => {
        downloadFileById(row.id);
      },
      hide: (row: any) => {
        return row.dataType !== 2 || !parsePermission(row.permissionValue).export;
      },
    },
    {
      title: t('通用.编辑'),
      type: 'primary',
      click: (row: any) => {
        editFileFun(row);
      },
      hide: (row: any) => {
        return (
          row.dataType !== 2 ||
          row.approvalStatus === 'pending' ||
          !parsePermission(row.permissionValue).write
        );
      },
    },
    {
      title: t('通用.删除'),
      type: 'danger',
      click: (row: any) => {
        delFileFun(row);
      },
      hide: (row: any) => {
        return (
          row.dataType !== 2 ||
          row.approvalStatus === 'pending' ||
          !parsePermission(row.permissionValue).delete
        );
      },
    },
  ];
});
const searchFun = (data: object) => {
  isSearching.value = true;
  if (!memoryFolder.value && currentFolder.value) {
    memoryFolder.value = currentFolder.value;
    currentFolder.value = null;
  }
  searchParams.value = cloneDeep(data);
  searchParams.value.searchType = 1;
  searchParams.value.parentDirId = memoryFolder.value?.id || '';
  searchParams.value.dirType = DIR_TYPE.KNOWLEDGE;
};
const resetFun = (data: object) => {
  isSearching.value = false;
  currentFolder.value = memoryFolder.value;
  searchParams.value = cloneDeep(data);
  searchParams.value.fileId = currentFolder.value?.id || '';
  searchParams.value.dirType = DIR_TYPE.KNOWLEDGE;
};
const refreshTableFun = async () => {
  baseTableRef.value?.resetFun();
};
const onFolderConfirmFun = async (formData: any) => {
  folderConfirmLoading.value = true;
  try {
    if (currentFolderMode.value === 'add') {
      const req = {
        dirType: DIR_TYPE.KNOWLEDGE,
        parDirId: currentFolder.value?.id,
        dirName: formData.name,
        type: 0,
      };
      const res: any = await dataCreateDirApi(req);
      if (res.code === 200) {
        refreshTreeAfterAdd(currentFolder.value);
        folderModalVisible.value = false;
        ElMessage.success(res.message);
      }
    } else if (currentFolderMode.value === 'edit') {
      const req = {
        dirId: currentFolder.value.id,
        oldName: currentFolder.value.originalName,
        newName: formData.name,
        type: 0,
      };
      const res: any = await dataRenameDirApi(req);
      if (res.code === 200) {
        refreshTreeAfterModifyOrRemove(currentFolder.value);
        folderModalVisible.value = false;
        ElMessage.success(res.message);
      }
    }
  } finally {
    folderConfirmLoading.value = false;
  }
};
const visible = ref(false);
const confirmLoading = ref(false);
const infoVisible = ref(false);
const currentRow = ref();
const openModalFun = () => {
  visible.value = true;
  currentRow.value = null;
};
const onConfirmFun = async (formData: any) => {
  let res: any;
  confirmLoading.value = true;
  try {
    if (currentRow.value && currentRow.value.id) {
      const file = formData.file?.[0];
      const req = {
        ...currentRow.value,
        templateId: formData.templateId,
        templateName: formData.templateName,
        file: file?.raw,
        fileName: file?.fileName,
        size: file?.size,
        projectName: formData.projectName,
        path: currentFolder.value.objectKey,
        dirId: currentFolder.value.id,
        chunk: 0,
        remarks: formData.remarks,
        projectId: formData.projectId,
        chunkTotal: 0,
        encryptKey: null,
        type: 0,
        analysisDirectionId: formData.analysisDirectionId,
        simulationPoolInfoListStr: JSON.stringify(formData.simulationPoolInfoList),
      };
      delete req.poolInfos;
      res = await dataUpdateFileApi(req);
    } else {
      const req = {
        sourceFiles: formData.file,
        uploadTaskId: new Date().getTime(),
        dirId: currentFolder.value.id,
        projectId: formData.projectId,
        analysisDirectionId: formData.analysisDirectionId,
        templateId: formData.templateId,
        templateName: formData.templateName,
        remarks: formData.remarks,
        type: 0,
        simulationPoolInfoList: formData.simulationPoolInfoList,
      };
      res = await batchAddFileInfoApi(req);
      if (res.code === 200) {
        res.data.forEach((item: any, index: number) => {
          emitter.emit('ADD_UPLOAD_FILE', {
            file: formData.originalName[index].raw, // 文件对象
            data: {
              // 接口返回的文件目录信息，包括配置信息
              ...item,
              isApprove: 1, // 0否 1是
              taskType: 2, // 2知识库
            },
          });
        });
      }
    }
    if (res.code === 200) {
      visible.value = false;
      refreshTableFun();
      ElMessage.success(res.message);
    }
  } finally {
    confirmLoading.value = false;
  }
};
const previewVisible = ref(false);
const previewFileFun = (row: any) => {
  currentRow.value = row;
  previewVisible.value = true;
};

const editFileFun = (row: any) => {
  currentRow.value = row;
  visible.value = true;
};
const approveDelVisible = ref(false);
const approveDelParams = ref<any>({});
const approveDelDirVisible = ref(false);
const approveDelDirParams = ref<any>({});
const currentFolderToDelete = ref<any>(null);
const onDelDirConfirmFun = () => {
  refreshTreeAfterModifyOrRemove(currentFolderToDelete.value);
};
const delFileFun = (row: any) => {
  currentRow.value = row;
  approveDelParams.value = { delFileId: row.id };
  approveDelVisible.value = true;
};
const onCellDblclickFun = (e: any) => {
  if (e.row.dataType === 1) {
    fileTreeRef.value?.openDirFun(e.row.id);
  }
};
const apiName: any = ref(null);
watchEffect(() => {
  if (currentFolder.value && currentFolder.value.id && !isSearching.value) {
    searchParams.value.fileId = currentFolder.value?.id || '';
    apiName.value = dataQueryDirApi;
  } else if (isSearching.value) {
    apiName.value = dataFileSearchApi;
  } else {
    apiName.value = dataFileSearchApi;
  }
});

const processVisible = ref(false);
const openProcessFun = (row: any) => {
  currentRow.value = row;
  processVisible.value = true;
};
</script>

<style lang="scss" scoped>
.gl-page-content-grey-full {
  .content {
    height: 100%;
    .options {
      margin-bottom: var(--margin-small);
    }
    .right-table {
      display: flex;
      flex-direction: column;
      height: 100%;
      .table {
        flex: 1;
        height: 0;
      }
    }
  }
}
</style>
