<template>
  <el-dialog :title=lang.view :class="{ fullStyle: full }" :visible.sync="dialogVisible" width="700px" class="el-dialogClass"
    :before-close="handleClose">
    <div slot="title" class="header-title">
      <div>{{lang.view}}</div>
      <div class="full">
        <img src="../../../../assets/fullScreen.png" alt="" @click="fullTools" />
      </div>
    </div>
    <div class="container">
      <div class="contentBox" v-loading="isLoading">
        <div class="content rowCloumn">
          <div class="title">{{lang.Summary}}</div>
          <div class="text">{{ data.summary || data.cdetail }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.FileName}}</div>
          <div class="text">{{ data.title }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.Format}}</div>
          <div class="text">{{ data.documentType }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.uploadTime2}}</div>
          <div class="text">{{ data.time }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.uploadStatus}}</div>
          <div class="text">{{ getState(data.ingestionStatus) }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.extractStatus}}</div>
          <div class="text">{{ getState2(data.extractionStatus) }}</div>
        </div>
        <div class="content">
          <div class="title">{{lang.owner}}</div>
          <div class="text">{{ getState2(data.username) }}</div>
        </div>
      </div>
      <div class="nav">
        <span :class="{ active: type == 1 }" @click="type = 1">{{lang.chunks}}</span>
        <span :class="{ active: type == 2 }" @click="type = 2">{{lang.knowledgeGraph}}</span>
        <span :class="{ active: type == 3 }" @click="type = 3">{{lang.Entities}}</span>
        <span :class="{ active: type == 4 }" @click="type = 4">{{lang.relationShip}}</span>
      </div>
      <div class="chunkBox" v-show="type == 1" v-loading="chunksLoading">
        <div class="chunks" v-for="(item, index) in chunksArray" :key="index">
          {{ item.text }}
        </div>
        <div class="noneData" v-if="!chunksArray.length">{{lang.sliceDataNull}}</div>
        <el-pagination v-if="chunksArray.length > 0" style="margin-top: 10px" background layout="prev, pager, next"
          :page-size="limit" :total="total" :current-page="page" @current-change="handleCurrentChange">
        </el-pagination>
      </div>
      <div class="chunkBox" v-show="type == 3" v-loading="entitiesLoading">
        <div class="chunks" v-for="(item, index) in entitiesArray" :key="index">
          <div class="chunksBox">
            <div><span class="title">{{lang.entityName}}</span><span>{{ item.name }}</span></div>
            <div><span class="title">{{lang.description}}：</span><span>{{ item.description }}</span></div>
          </div>
        </div>
        <div class="noneData" v-if="!entitiesArray.length">{{lang.entDataNull}}</div>
        <el-pagination v-if="entitiesArray.length > 0" style="margin-top: 10px" background layout="prev, pager, next"
          :page-size="limit2" :total="total2" :current-page="page2" @current-change="handleCurrentChange2">
        </el-pagination>
      </div>
      <div class="chunkBox" v-show="type == 4" v-loading="relationshipsLoading">
        <div class="chunks" v-for="(item, index) in relationshipsArray" :key="index">
          <div class="chunksBox">
            <div><span class="title">{{lang.relationShip}}：</span><span>{{ item.subject }} {{ item.predicate }} {{ item.object }}</span>
            </div>
            <div><span class="title">{{lang.description}}：</span><span>{{ item.description }}</span></div>
          </div>
        </div>
        <div class="noneData" v-if="!relationshipsArray.length">{{lang.reaDataNUll}}</div>
        <el-pagination v-if="relationshipsArray.length > 0" style="margin-top: 10px" background
          layout="prev, pager, next" :page-size="limit3" :total="total3" :current-page="page3" @current-change="handleCurrentChange3">
        </el-pagination>
      </div>
      <div class="tuBox" v-if="type == 2" v-loading="graphLoading">
        <div v-if="!Object.keys(graphJson).length" class="noneData">{{lang.graphDataNull}}</div>
        <graph ref="graphComponent" v-if="Object.keys(graphJson).length" :Json="graphJson"></graph>
      </div>
    </div>
    <span slot="footer">
      <el-button @click="dialogVisible = false">{{lang.close}}</el-button>
    </span>
  </el-dialog>
</template>

<script>
import graph from "./graph.vue";
export default {
  components: {
    graph
  },
  data() {
    return {
      dialogVisible: false,
      data: {},
      did: "",
      isLoading: false,
      type: 1,
      limit: 10,
      total: 0,
      page: 1,
      chunksArray: [],
      chunksLoading: false,
      limit2: 10,
      total2: 0,
      page2: 1,
      entitiesArray: [],
      entitiesLoading: false,
      limit3: 10,
      total3: 0,
      page3: 1,
      relationshipsArray: [],
      relationshipsLoading: false,
      graphJson: {},
      graphLoading: false,
      full: false,
    };
  },
  watch: {
    full() {
      // The DOM update and CSS transition need time.
      setTimeout(() => {
        if (this.$refs.graphComponent) {
          this.$refs.graphComponent.handleResize();
        }
      }, 300);
    }
  },
  computed: {
    getState() {
      return function (item) {
        if (item == "success") {
          return this.lang.success;
        } else if (item == "failed") {
          return this.lang.fail;
        } else if (item == "augmenting") {
          return this.lang.uploading;
        } else if (item == "pending") {
          return this.lang.pending;
        } else if (item == "enriched") {
          return "enriched";
        } else if (!item) {
          return this.lang.uploading;
        } else {
          return item;
        }
      };
    },
    getState2() {
      return function (item) {
        if (item == "success") {
          return this.lang.success;
        } else if (item == "failed") {
          return this.lang.fail;
        } else if (item == "pending") {
          return this.lang.pending;
        } else if (item == "processing") {
          return this.lang.processing;
        } else if (item == "enriched") {
          return "enriched";
        } else if (!item) {
          return this.lang.uploading;
        } else {
          return item;
        }
      };
    }
  },
  methods: {
    handleClose(done) {
      done();
    },
    openG(did) {
      this.did = did;
      this.dialogVisible = true;
      this.type = 1;
      this.page = 1;
      this.page2 = 1;
      this.page3 = 1;
      this.chunksArray = []
      this.entitiesArray = []
      this.relationshipsArray = []
      this.getFileDetail();
      this.getChunks();
      this.setGrapJson();
      this.getEntities();
      this.getRelationships();
    },
    getFileDetail() {
      this.isLoading = true;
      let params = {
        documentId: this.did
      };
      this.ajax
        .post(this.$store.state.fileApi + "getFileDetail", [params])
        .then(res => {
          this.isLoading = false;
          console.log(res.data);
          this.data = res.data.result;
        })
        .catch(err => {
          this.isLoading = false;
          console.error(err);
        });
    },
    getChunks() {
      this.chunksLoading = true;
      let params = {
        documentId: this.did,
        page: this.page
      };
      // 获取切片
      this.ajax
        .post(this.$store.state.fileApi + "getChunks", [params])
        .then(res => {
          this.chunksLoading = false;
          console.log(res.data);
          this.total = res.data.result.totalEntries;
          this.chunksArray = res.data.result.results;
        })
        .catch(err => {
          this.chunksLoading = false;
          this.chunksArray = [];
          console.error(err);
        });
    },
    handleCurrentChange(val) {
      this.page = val;
      this.getChunks();
    },
    getEntities() {
      this.entitiesArray = [];
      this.entitiesLoading = true;
      let params = {
        documentId: this.did,
        page: this.page2
      };
      // 获取切片
      this.ajax
        .post(this.$store.state.fileApi + "getEntities", [params])
        .then(res => {
          this.entitiesLoading = false;
          console.log(res.data);
          this.total2 = res.data.result.totalEntries;
          this.entitiesArray = res.data.result.results;
        })
        .catch(err => {
          this.entitiesLoading = false;
          this.entitiesArray = [];
          console.error(err);
        });
    },
    handleCurrentChange2(val) {
      this.page2 = val;
      this.getEntities();
    },
    getRelationships() {
      this.relationshipsArray = [];
      this.relationshipsLoading = true;
      let params = {
        documentId: this.did,
        page: this.page3
      };
      // 获取切片
      this.ajax
        .post(this.$store.state.fileApi + "getRelationships", [params])
        .then(res => {
          this.relationshipsLoading = false;
          console.log(res.data);
          this.total3 = res.data.result.totalEntries;
          this.relationshipsArray = res.data.result.results;
        })
        .catch(err => {
          this.relationshipsLoading = false;
          this.relationshipsArray = []
          console.error(err);
        });
    },
    handleCurrentChange3(val) {
      this.page3 = val;
      this.getRelationships();
    },
    generateDynamicJson(relationships) {
      // 用于存储节点和连线的对象
      let nodes = [];
      let lines = [];
      let nodeIds = new Set(); // 用来记录已生成的节点ID，避免重复

      // 遍历关系数据并动态生成节点和连线
      relationships.forEach(relation => {
        // 添加subject和object为节点
        if (!nodeIds.has(relation.subject)) {
          nodes.push({
            id: relation.subject,
            text: relation.subject,
            borderColor: "yellow"
          });
          nodeIds.add(relation.subject);
        }

        if (!nodeIds.has(relation.object)) {
          nodes.push({
            id: relation.object,
            text: relation.object,
            borderColor: "yellow"
          });
          nodeIds.add(relation.object);
        }

        // 创建连线
        lines.push({ from: relation.subject, to: relation.object });
      });

      // 返回最终的结构
      return {
        rootId: "a",
        nodes,
        lines
      };
    },
    fullTools() {
      this.full = !this.full
    },
    transformData(data) {
      const nodes = [];
      const lines = [];

      // 构建节点
      const nodeMap = new Map();

      data.results.forEach(item => {
        const subject = item.subject;
        const object = item.object;

        if (!nodeMap.has(subject)) {
          nodeMap.set(subject, { id: subject, text: subject, data: {} });
          nodes.push(nodeMap.get(subject));
        }

        if (!nodeMap.has(object)) {
          nodeMap.set(object, { id: object, text: object, data: {} });
          nodes.push(nodeMap.get(object));
        }

        // 添加关系线
        lines.push({
          from: subject,
          to: object
        });
      });

      return {
        rootId: (nodes.length > 0 ? nodes[0].id : 'root'),
        nodes: nodes,
        lines: lines
      };
    },
    transformData2(data, Entities) {
      // 优化：先将Entities转为Map，提升查找效率
      const entityMap = new Map();
      (Entities.results || []).forEach(ent => {
        entityMap.set(ent.id, {category: ent.category || '', description: ent.description || ''});
      });

      const nodes2 = [];
      const lines2 = [];
      const nodeMap2 = new Map();

      // 辅助函数：添加节点
      const addNode = (id, label) => {
        if (!nodeMap2.has(id)) {
          const Entitie = entityMap.get(id) || '';
          const node = { id, label, category:Entitie.category, description: Entitie.description};
          nodeMap2.set(id, node);
          nodes2.push(node);
        }
      };

      (data.results || []).forEach(item => {
        const { subject, object, subjectId, objectId, predicate } = item;
        addNode(subjectId, subject);
        addNode(objectId, object);

        // 添加关系线
        lines2.push({
          source: subjectId,
          target: objectId,
          predicate
        });
      });

      // 输出调试信息
      console.log({
        nodes: nodes2,
        edges: lines2
      });

      return {
        nodes: nodes2,
        edges: lines2
      };
    },
    setGrapJson() {
      this.graphLoading = true;
      let params = {
        documentId: this.did,
        limit: 1000,
      };
      // 获取切片
      this.ajax
        .post(this.$store.state.fileApi + "getEntitiesAndRelationships", [params])
        .then(res => {
          this.graphLoading = false;
          console.log(res.data);
          if (res.data.Relationships.results.length) {
            console.log(this.transformData2(res.data.Relationships, res.data.Entities));
            this.graphJson = this.transformData2(res.data.Relationships, res.data.Entities)
          }else {
            this.graphJson = {}
          }
          // this.graphJson = {
          //   rootId: "a",
          //   nodes: [
          //     { id: "a", text: "Border color", borderColor: "yellow" },
          //     { id: "a1", text: "No border", borderColor: "yellow" },
          //     { id: "a2", text: "Plain", borderColor: "yellow" },
          //     { id: "a1-1", borderColor: "yellow" },
          //     { id: "b", text: "b", borderColor: "yellow" },
          //     { id: "c", text: "c", borderColor: "yellow" }
          //   ],
          //   lines: [
          //     { from: "a", to: "b" },
          //     { from: "a", to: "c" },
          //     { from: "a", to: "a1" },
          //     { from: "a1", to: "a1-1" },
          //     { from: "a", to: "a2" }
          //   ]
          // };
        })
        .catch(err => {
          this.graphLoading = false;
          console.error(err);
        });

    }
  }
};
</script>

<style scoped>
.el-dialogClass>>>.el-dialog {
  margin: 0 auto !important;
  height: calc(100% - 100px);
  transform: translateY(-50%);
  top: 50%;
  border-radius: 8px;
}

.el-dialogClass>>>.el-dialog__header {
  padding: 20px 30px 10px;
  box-sizing: border-box;
}

.el-dialogClass>>>.el-dialog__body {
  height: calc(100% - 70px - 55px);
  overflow-y: auto;
  overflow-x: hidden;
  box-sizing: border-box;
  padding: 0 20px;
}

.container {
  height: 100%;
  padding: 0 10px;
  overflow: auto;
  /* box-sizing: border-box; */
}

.contentBox {
  width: 100%;
}

.rowCloumn {
  flex-direction: column;
}

.rowCloumn .text {
  margin-top: 8px;
}

.contentBox>.content {
  display: flex;
  justify-content: space-between;
  font-size: 15px;
  color: #323232;
  padding: 10px 0;
  border-bottom: 1px solid #f3f3f3;
}

.contentBox>.content>.title {}

.contentBox>.content>.text {
  line-height: 22px;
}

.nav {
  width: 100%;
  height: 40px;
  display: flex;
  align-items: center;
  background: #f8f8f8;
  margin: 15px 0;
  border-radius: 5px;
  padding: 5px;
  box-sizing: border-box;
  color: #a3a3a3;
}

.nav>span {
  height: 100%;
  display: flex;
  align-items: center;
  width: calc(100% / 2);
  justify-content: center;
  border-radius: 5px;
  cursor: pointer;
}

.nav>span.active {
  background: #fff;
  color: #000;
}

.noneData {
  width: 100%;
  text-align: center;
  margin: 20px 0;
  color: #000;
}

.chunkBox {
  width: 100%;
}

.chunks {
  width: 100%;
  background: #f8f9fc;
  border-radius: 5px;
  box-sizing: border-box;
  padding: 10px;
  color: rgb(15, 21, 40);
  line-height: 20px;
}

.chunks+.chunks {
  margin-top: 10px;
}

.chunksBox {}

.chunksBox>div {}

.chunksBox>div>span {}

.chunksBox>div>span.title {
  font-weight: 600;
}

.fullStyle>>>.el-dialog,
.fullStyle {
  width: 100% !important;
  max-width: 100% !important;
  height: 100% !important;
  margin: 0 !important;
}

.header-title {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.header-title .full {
  height: 16px;
  cursor: pointer;
  margin-right: 10px;
}

.header-title .full img {
  height: 100%;
}
</style>
