<template>
  <div class="data-list" v-loading="loading" element-loading-text="加载中...">
    <div class="batch-actions" style="margin: 10px 0">
      <el-button
        type="primary"
        @click="batchAnalysis"
        :disabled="!selectedRows.length"
        >批量解析</el-button
      >
    </div>
    <el-table
      ref="dataTable"
      :data="dataList"
      style="width: 100%"
      header-row-class-name="headerBg"
      empty-text="没有模板信息"
      @selection-change="handleSelectionChange"
      @sort-change="handleSortChange"
    >
      <el-table-column type="selection" width="55"></el-table-column>
      <el-table-column prop="id" label="ID" align="center" width="80" />
      <el-table-column
        prop="name"
        label="文件名称"
        align="center"
        sortable="custom"
      >
        <template #default="scope">
          <span>{{ scope.row.name }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="type" label="文件类型" align="center" />
      <el-table-column prop="chunk_num" label="分块数" align="center" />
      <el-table-column
        prop="create_time"
        label="上传时间"
        align="center"
        sortable="custom"
      />
      <el-table-column prop="run" label="解析状态" align="center">
        <template #default="scope">
          <div v-if="scope.row.run == 0">未解析</div>
          <div v-if="scope.row.run == 1">解析中</div>
          <div v-if="scope.row.run == 3">成功</div>
          <div v-if="scope.row.run == 4">失败</div>
          <div v-if="scope.row.run == 5">待处理</div>
          <div v-if="scope.row.run == 6">文件异常</div>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="330">
        <template #default="scope">
          <div class="btns">
            <el-tooltip
              class="item"
              effect="dark"
              content="预览"
              placement="top"
            >
              <el-button
                type="text"
                size="small"
                circle
                icon="el-icon-view"
                v-if="allowEdit"
                style="font-size: 20px"
                @click="getName(scope.row)"
              ></el-button
            ></el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              :content="
                scope.row.run === 1 || scope.row.run === 5 ? '解析中' : '解析'
              "
              placement="top"
            >
              <el-button
                v-if="scope.row.run !== 1 && scope.row.run !== 5"
                type="text"
                icon="el-icon-caret-right"
                circle
                @click="analysis(scope.row)"
                style="font-size: 20px"
              >
              </el-button>
              <el-button
                v-else
                type="text"
                icon="el-icon-loading"
                circle
                :disabled="true"
                style="font-size: 20px"
              >
              </el-button>
            </el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              content="解析方法"
              placement="top"
            >
              <el-button
                type="text"
                size="small"
                circle
                icon="el-icon-tickets"
                v-if="allowEdit"
                style="font-size: 20px"
                @click="Analytical(scope.row)"
              ></el-button
            ></el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              content="修改文件名"
              placement="top"
            >
              <el-button
                type="text"
                size="small"
                circle
                icon="el-icon-edit"
                v-if="allowEdit"
                style="font-size: 20px"
                @click="btnEdit(scope.row)"
              ></el-button
            ></el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              content="下载"
              placement="top"
            >
              <el-button
                type="text"
                size="small"
                circle
                icon="el-icon-download"
                v-if="allowEdit"
                @click="btnDown(scope.row)"
                :loading="scope.row.downloading"
                style="font-size: 20px"
              ></el-button
            ></el-tooltip>
            <el-tooltip
              class="item"
              effect="dark"
              content="删除"
              placement="top"
            >
              <el-button
                type="text"
                size="small"
                circle
                icon="el-icon-delete"
                v-if="allowDelete"
                @click="btnDelete(scope.row.id)"
                style="font-size: 20px"
              ></el-button
            ></el-tooltip>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <div class="page-info">
      <el-pagination
        :currentPage="queryForm.page"
        :page-size="queryForm.pageSize"
        :total="recordCount"
        :page-count="pageTotal"
        :page-sizes="[10, 20, 50, 100]"
        background
        layout="sizes, prev, pager, next"
        @current-change="ChangePage"
        @size-change="handleSizeChange"
      >
      </el-pagination>
    </div>
    <el-dialog
      title="修改名称"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose"
    >
      <el-form :model="wordForm" ref="wordRef" :rules="wordRules">
        <el-form-item label="文件名称:" prop="new_name">
          <el-input
            v-model="wordForm.new_name"
            placeholder="请输入文件名称"
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="submitBuck">确 定</el-button>
      </span>
    </el-dialog>

    <!-- 解析方法 -->
    <el-dialog
      title="解析方法"
      :visible.sync="anaDialogVisible"
      width="30%"
      :before-close="handleAnalClose"
    >
      <el-form
        :model="analForm"
        ref="analRef"
        label-position="top"
        :rules="analRules"
      >
        <el-form-item label="页码范围:" prop="new_name">
          <el-input-number
            v-model="analForm.start_page"
            controls-position="right"
            :min="1"
          ></el-input-number>
          <el-input-number
            v-model="analForm.end_page"
            controls-position="right"
            :min="1"
            style="margin-left: 10px"
          ></el-input-number>
        </el-form-item>
        <el-form-item label="块token数">
          <div class="block">
            <el-slider v-model="analForm.token_num" :max="2048" show-input>
            </el-slider>
          </div>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="handleAnalClose">取 消</el-button>
        <el-button type="primary" @click="submitAnal">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  getBucketContents,
  deleteFile,
  nameGetUrl,
  renameFile,
  analysis,
  batchAnalysis,
  getRunStatus,
} from "@/api/knowledge";
export default {
  props: {
    queryForm: {
      type: Object,
      default: () => {
        return {
          page: 1,
          pageSize: 10,
          id: "",
        };
      },
    },
    allowEdit: {
      type: Boolean,
      default: false,
    },
    allowDelete: {
      type: Boolean,
      default: false,
    },
  },
  watch: {
    queryForm: {
      handler: function (val) {
        this.search();
      },
      // immediate: true,//立即执行
      deep: true,
    },
  },
  data() {
    // 自定义验证函数
    const validateBucketName = (rule, value, callback) => {
      const regex = /^[a-z0-9-]{3,63}$/;
      if (!regex.test(value)) {
        callback(
          new Error(
            "名称必须在 3-63 个字符之间，只能包含小写字母、数字和连字符"
          )
        );
      } else {
        callback();
      }
    };
    return {
      loading: false,
      dialogVisible: false, //控制产品审核
      currentDataId: 0,
      recordCount: 0,
      pageTotal: 1,
      dataList: [],
      currentData: {},
      dialogVisible: false,
      wordForm: {
        document_id: "",
        new_name: "",
      },
      wordRules: {
        new_name: [
          { required: true, message: "请输入文件名称", trigger: "blur" },
          /* { validator: validateBucketName, trigger: "blur" }, */
        ],
      },
      anaDialogVisible: false,
      analForm: {
        start_page: 1,
        end_page: 10000,
        token_num: 0,
      },
      analRules: {},
      selectedRows: [],
      sortColumn: "",
      sortOrder: "",
      analysisStatusCheckers: {}, // 新增：用于存储每个文档的状态检查器
    };
  },
  mounted() {
    this.search();
  },
  beforeDestroy() {
    Object.values(this.analysisStatusCheckers).forEach(clearTimeout);
  },
  methods: {
    /* 排序 */
    handleSortChange({ prop, order }) {
      this.sortColumn = prop;
      this.sortOrder = order;
      this.sortData();
    },

    sortData() {
      const { sortColumn, sortOrder } = this;
      if (!sortColumn || !sortOrder) {
        this.search(); // Reset to original order
        return;
      }

      this.dataList.sort((a, b) => {
        let comparison = 0;
        if (sortColumn === "name") {
          comparison = a.name.localeCompare(b.name, "zh-CN");
        } else if (sortColumn === "create_time") {
          comparison = new Date(a.create_time) - new Date(b.create_time);
        }
        return sortOrder === "ascending" ? comparison : -comparison;
      });
    },
    /* 批量解析 */
    handleSelectionChange(val) {
      this.selectedRows = val;
    },

    batchAnalysis() {
      const selectedIds = this.selectedRows.map((row) => row.id);
      if (selectedIds.length === 0) {
        this.$message.warning("请选择要解析的文件");
        return;
      }

      this.$confirm("确定要批量解析选中的文件吗？", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        .then(() => {
          this.loading = true;
          batchAnalysis({ ids: JSON.stringify(selectedIds) })
            .then((res) => {
              if (res.status === 200) {
                this.$message.success("批量解析任务已提交");
                this.updateAnalysisStatus(selectedIds);
                this.clearSelection();
              } else {
                this.$message.error("批量解析请求失败");
              }
            })
            .catch((error) => {
              console.error("批量解析错误:", error);
              this.$message.error("批量解析过程中出现错误");
            })
            .finally(() => {
              this.loading = false;
            });
        })
        .catch(() => {
          // 取消操作
        });
    },

    updateAnalysisStatus(ids) {
      this.dataList.forEach((row) => {
        if (ids.includes(row.id)) {
          row.run = 1; // 设置状态为"解析中"
          this.startAnalysisStatusChecker(row);
        }
      });
    },

    clearSelection() {
      this.$refs.dataTable.clearSelection();
      this.selectedRows = [];
    },

    /* 跳转页面 */
    getName(e) {
      /* this.$router.push({
        path: "/knowledge/category/infoList",
        query: { id: e.id, type: e.type },
      }); */
      let _this = this;
      let a = document.createElement("a");
      a.href = `#/infoList?id=${e.id}&type=${e.type}`; // 使用 hash
      a.target = "_blank";
      a.click();
    },
    /* 解析 */
    analysis(row) {
      if (row.run === 1 || row.run === 5) return;

      this.$set(row, "run", 1);

      analysis({
        document_id: row.id,
        start_page: row.start_page || 0,
        end_page: row.end_page || 1000,
        max_tokens: row.token_num,
      })
        .then((res) => {
          if (res.status === 200) {
            this.startAnalysisStatusChecker(row);
          } else {
            this.$message.error("解析请求失败");
            this.$set(row, "run", 0);
          }
        })
        .catch((error) => {
          console.error("解析错误:", error);
          this.$message.error("解析过程中出现错误");
          this.$set(row, "run", 0);
        });
    },

    startAnalysisStatusChecker(row) {
      // 如果已经有一个检查器在运行，先停止它
      if (this.analysisStatusCheckers[row.id]) {
        clearTimeout(this.analysisStatusCheckers[row.id]);
      }

      const checkStatus = () => {
        getRunStatus({ document_id: row.id })
          .then((res) => {
            if (res.status === 200) {
              const newStatus = Number(res.data.run);
              this.$set(row, "run", newStatus);

              if (newStatus === 3) {
                this.$message.success("解析成功");
                delete this.analysisStatusCheckers[row.id];
              } else if (newStatus === 4) {
                this.$message.error("解析失败");
                delete this.analysisStatusCheckers[row.id];
              } else if (newStatus === 1 || newStatus === 5) {
                // 继续检查
                this.analysisStatusCheckers[row.id] = setTimeout(
                  checkStatus,
                  5000 + Math.random() * 5000
                );
              }
            } else {
              this.$message.error("获取解析状态失败");
              this.$set(row, "run", 0);
              delete this.analysisStatusCheckers[row.id];
            }
          })
          .catch((error) => {
            console.error("获取解析状态错误:", error);
            this.$message.error("获取解析状态时出现错误");
            this.$set(row, "run", 0);
            delete this.analysisStatusCheckers[row.id];
          });
      };

      // 立即开始第一次检查
      checkStatus();
    },

    handleAnalClose() {
      this.anaDialogVisible = false;
    },
    /* 确认 */
    submitAnal() {
      this.dataList.map((el) => {
        if (this.analForm.id == el.id) {
          el.start_page = this.analForm.start_page;
          el.end_page = this.analForm.end_page;
          el.token_num = this.analForm.token_num;
        }
      });
      this.anaDialogVisible = false;
    },
    /* 解析方法 */
    Analytical(e) {
      this.analForm.id = e.id;
      this.analForm.token_num = e.token_num;
      this.anaDialogVisible = true;
    },
    editWidth() {
      if (this.allowDelete && this.allowEdit) {
        return 200;
      }
      if (this.allowDelete || this.allowEdit) {
        return 120;
      }
      return 100;
    },

    onFocusVal(e) {
      let _this = this;
      _this.currentDataId = e.target.dataset.id;
    },

    onChangeVal(e) {
      let _this = this;
      let par = {
        id: _this.currentDataId,
        val: e,
      };
    },

    btnDelete(e) {
      let _this = this;
      let par = {
        document_id: e,
      };
      _this
        .$confirm("您是否确认删除该记录？", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning",
        })
        .then((res) => {
          deleteFile(par).then((res) => {
            if (res.status !== 200) return;
            _this.$message.success(res.data);
            _this.search();
          });
        })
        .catch(() => {});
    },

    searchData() {
      let _this = this;
      _this.dialogVisible = false;
      _this.search();
    },
    /* 关闭 */
    handleClose(done) {
      done();
    },
    /* 修改文件名 */
    btnEdit(e) {
      this.wordForm.new_name = e.name;
      this.wordForm.document_id = e.id;
      this.dialogVisible = true;
    },
    /* 提交 */
    submitBuck() {
      this.$refs.wordRef.validate((valid) => {
        if (valid) {
          renameFile(this.wordForm).then((res) => {
            if (res.status !== 200) return;
            this.search();
            this.dialogVisible = false;
            this.wordForm = {
              new_name: "",
              document_id: "",
            };
          });
        } else {
          this.$message.error("请填写文档名称");
        }
      });
    },

    //下载
    btnDown(e) {
      // Set downloading flag for this specific row
      this.$set(e, "downloading", true);

      nameGetUrl({
        document_id: e.id,
      })
        .then((res) => {
          if (res.status !== 200) {
            this.$message.error("获取下载链接失败");
            return;
          }

          return fetch(res.data.url);
        })
        .then((response) => response.blob())
        .then((blob) => {
          const url = window.URL.createObjectURL(blob);
          const link = document.createElement("a");
          link.href = url;
          link.download = e.name;
          document.body.appendChild(link);
          link.click();
          setTimeout(() => {
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
          }, 100);
        })
        .catch((error) => {
          console.error("下载出错:", error);
          this.$message.error("下载失败，请稍后重试");
        })
        .finally(() => {
          // Reset downloading flag when done
          this.$set(e, "downloading", false);
        });
    },

    handleClose() {
      let _this = this;
      _this.currentData = {};
      _this.dialogVisible = false;
    },

    //搜索
    search() {
      let _this = this;
      _this.loading = true;
      getBucketContents(_this.queryForm)
        .then((res) => {
          if (res.status !== 200) return;
          _this.dataList = res.data.documents.map((el) => ({
            ...el,
            token_num: 256,
            start_page: _this.analForm.start_page,
            end_page: _this.analForm.end_page,
          }));
          _this.pageTotal = res.data.pagination.total_count;
          _this.recordCount = res.data.pagination.total_count;
          _this.queryForm.pageSize = res.data.pagination.total_size;
          _this.loading = false;

          // Initialize the analysis status for each row
          _this.dataList.forEach((row) => {
            if (row.run === 1) {
              _this.startAnalysisStatusChecker(row);
            }
          });
        })
        .catch(() => {
          _this.loading = false;
        });
    },
    //修改分页
    ChangePage(e) {
      let _this = this;
      _this.queryForm.page = e;
      _this.search();
    },
    handleSizeChange(val) {
      this.queryForm.pageSize = val;
      this.queryForm.page = 1; // Reset to first page when changing page size
      this.search();
    },
  },
};
</script>

<style lang="scss">
@import "./dataList.scss";
</style>
