<template>
  <div class="gl-page-content-grey-full">
    <div class="content">
      <FileTree
        ref="fileTreeRef"
        :api="listDirApi"
        :params="{ dirType: dirType }"
        @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="tableName"
                :api="apiName"
                :params="searchParams"
                showIndex
                :actionList="actionList"
                :exportApi="dataExportKnowledgeListApi"
                fullHeight
                :exportFileName="$t('知识库.知识库列表')"
                :exportParams="{
                  ...searchParams,
                  parentDirId: currentFolder?.id || '',
                }"
                @cell-dblclick="onCellDblclickFun"
              >
                <template #leftOptions>
                  <div>
                    <el-button
                      :icon="DArrowLeft"
                      :disabled="navList.length <= 1"
                      @click="backFun"
                      >{{ $t('通用.返回上一级') }}</el-button
                    >
                    <el-button
                      v-if="folderPermission.import"
                      type="primary"
                      :icon="Plus"
                      :disabled="!currentFolder"
                      @click="openModalFun"
                    >
                      {{ $t('知识库.上传') }}
                    </el-button>
                    <el-button :disabled="!currentFolder" @click="infoVisible = true">
                      {{ $t('知识库.基本信息') }}
                    </el-button>
                  </div>
                </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 v-if="needApproval" #approvalStatus="{ row, column }">
                  <template v-if="row.dataType === 2">
                    <el-button
                      v-if="row[column.field] === 'pending'"
                      type="primary"
                      link
                      @click="openProcessFun(row)"
                    >
                      {{ KNOWLEDGE_APPROVE_STATUS.O[row[column.field]] }}
                    </el-button>
                    <el-button v-else type="primary" link @click="openProcessFun(row)">
                      {{ $t('知识库.审批完成') }}
                    </el-button>
                  </template>
                </template>
                <template v-if="needApproval" #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-if="needApproval" v-model="processVisible" :flowId="currentRow?.cidFlowId" />
    <!-- 上传/编辑弹窗 -->
    <DetailModal
      v-model="visible"
      :detail="currentRow"
      :folder="currentFolder"
      :tableName="tableName"
      :moduleCode="moduleCode"
      :itemNum="needApproval ? 6 : 5"
      :confirmLoading="confirmLoading"
      @confirm="onConfirmFun"
    />
    <!-- 文件夹弹窗 -->
    <FolderModal
      v-model="folderModalVisible"
      :detail="currentFolder"
      :mode="currentFolderMode"
      :confirmLoading="folderConfirmLoading"
      @confirm="onFolderConfirmFun"
    />
    <!-- 文件预览 -->
    <FilePreview v-model="previewVisible" :fileId="currentRow?.id" />
    <!-- 基本信息抽屉 -->
    <InfoDrawer v-model="infoVisible" :data="currentFolder" />
    <!-- 需要审批时的删除弹窗 -->
    <ApproveDel
      v-if="needApproval"
      v-model="approveDelVisible"
      :api="dataDelFileApi"
      :params="approveDelParams"
      :moduleCode="moduleCode"
      @confirm="refreshTableFun"
    />
    <ApproveDel
      v-if="needApproval"
      v-model="approveDelDirVisible"
      :api="dataDelDirApi"
      :params="approveDelDirParams"
      :moduleCode="moduleCode"
      @confirm="onDelDirConfirmFun"
    />
  </div>
</template>

<script lang="ts" setup>
/**
 * 资源库页面公共组件
 * 适用于：动画库、机器人库、工业设计库、公差分析库等
 * 通过 needApproval 区分是否需要审批流程
 */
import {
  computed,
  onActivated,
  onBeforeUnmount,
  onDeactivated,
  onMounted,
  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 DetailModal from './detailModal.vue';
import FolderModal from './folderModal.vue';
import InfoDrawer from './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, downloadFileById } from '@/utils/file';
import TableSearch from '@/components/common/table/tableSearch.vue';
import { cloneDeep } from 'lodash-es';
import { useDict } from '@/utils/useDict';
import ApprovalProcess from '@/components/common/approvalProcess/index.vue';
import ApproveDel from '@/components/common/approveDel/index.vue';
import { useI18n } from 'vue-i18n';
import FilePreview from '@/components/common/filePreview/index.vue';
import emitter from '@/utils/eventBus';
import PoolTaskSelect from '@/components/pool/poolTaskSelect.vue';
import { parsePermission } from '@/utils/permission';
import { useRoute } from 'vue-router';
import { TABLE_NAME } from '@/utils/enum/tableName';

interface Props {
  tableName?: string;
  dirType: number;
  needApproval?: boolean;
  moduleCode?: string;
}

const props = withDefaults(defineProps<Props>(), {
  tableName: TABLE_NAME.ANIMATION_LIBRARY,
  needApproval: false,
  moduleCode: '',
});

const route = useRoute();
const CALLBACK_FLAG = computed(() => route.path);

const listDirApi = (params: any) => {
  return dataListDirApi({ ...params, dirType: props.dirType });
};

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) => {
  if (props.needApproval) {
    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(() => {});
    }
  } else {
    // 不需要审批直接删除
    ElMessageBox.confirm(t('知识库.确认删除'), t('通用.提示'), {
      confirmButtonText: t('通用.确定'),
      cancelButtonText: t('通用.取消'),
      type: 'warning',
    })
      .then(() => removeFun(data))
      .catch(() => {});
  }
};

const removeFun = async (data: Data) => {
  const res: any = await dataDelDirApi({ delDirId: data.id });
  if (res.code === 200) {
    refreshTreeAfterModifyOrRemove(data);
    ElMessage.success(res.message);
  }
};

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: props.dirType,
});

// 操作按钮列表
const actionList = computed(() => {
  const list = [
    {
      title: t('通用.预览'),
      type: 'primary',
      click: (row: any) => previewFileFun(row),
      hide: (row: any) => row.dataType !== 2 || !parsePermission(row.permissionValue).read,
    },
    {
      title: t('通用.下载'),
      type: 'primary',
      click: (row: any) => downloadFileById(row.id),
      hide: (row: any) => row.dataType !== 2 || !parsePermission(row.permissionValue).export,
    },
    {
      title: t('通用.编辑'),
      type: 'primary',
      click: (row: any) => editFileFun(row),
      hide: (row: any) =>
        row.dataType !== 2 ||
        row.approvalStatus === 'pending' ||
        !parsePermission(row.permissionValue).write,
    },
  ];

  // 删除按钮根据是否需要审批有不同逻辑
  if (props.needApproval) {
    list.push({
      title: t('通用.删除'),
      type: 'danger',
      click: (row: any) => delFileWithApprovalFun(row),
      hide: (row: any) =>
        row.dataType !== 2 ||
        row.approvalStatus === 'pending' ||
        !parsePermission(row.permissionValue).delete,
    });
  } else {
    list.push({
      title: t('通用.删除'),
      type: 'danger',
      needConfirm: true,
      confirmTip: t('通用.确认删除吗'),
      click: (row: any) => delFileFun(row),
      hide: (row: any) =>
        row.dataType !== 2 ||
        row.approvalStatus === 'pending' ||
        !parsePermission(row.permissionValue).delete,
    } as any);
  }

  return list;
});

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 = props.dirType;
};

const resetFun = (data: object) => {
  isSearching.value = false;
  currentFolder.value = memoryFolder.value;
  searchParams.value = cloneDeep(data);
  searchParams.value.fileId = currentFolder.value?.id || '';
  searchParams.value.dirType = props.dirType;
};

const refreshTableFun = async () => {
  baseTableRef.value?.resetFun();
};

const onFolderConfirmFun = async (formData: any) => {
  folderConfirmLoading.value = true;
  try {
    if (currentFolderMode.value === 'add') {
      const req = {
        dirType: props.dirType,
        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: props.needApproval ? 1 : 0,
              taskType: 2,
              callbackFlag: CALLBACK_FLAG.value,
            },
          });
        });
      }
    }
    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 delFileFun = async (row: any) => {
  currentRow.value = row;
  try {
    const res: any = await dataDelFileApi({ delFileId: row.id });
    if (res.code === 200) {
      refreshTableFun();
      ElMessage.success(res.message);
    }
  } catch (error) {
    console.error(error);
  }
};

// 需要审批的删除
const approveDelVisible = ref(false);
const approveDelParams = ref<any>({});
const approveDelDirVisible = ref(false);
const approveDelDirParams = ref<any>({});
const currentFolderToDelete = ref<any>(null);

const delFileWithApprovalFun = (row: any) => {
  currentRow.value = row;
  approveDelParams.value = { delFileId: row.id };
  approveDelVisible.value = true;
};

const onDelDirConfirmFun = () => {
  refreshTreeAfterModifyOrRemove(currentFolderToDelete.value);
};

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;
};

// 上传完成回调
const uploadFinishedFun = (data: any) => {
  if (data.callbackFlag === CALLBACK_FLAG.value) {
    refreshTableFun();
  }
};

onMounted(() => {
  emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
});

onBeforeUnmount(() => {
  emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
});

onActivated(() => {
  emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
});

onDeactivated(() => {
  emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
});
</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>
