<template>
  <div class="communityNode-component">
    <div id="container" class="container" ref="teamContainer"></div>
  </div>
</template>

<script setup>
import { defineProps, onMounted, ref, defineEmits, defineExpose, watch } from "vue";
import * as echarts from "echarts";
import anchor from "@/assets/json/anchor_community.json";
import community from "@/assets/json/community_nodes.json";
import nodeHoverImg from "@/assets/images/nodeHover.png";
import { storeToRefs } from "pinia";
import { useKeyNodeRecognitionStore } from "@/store/keyNodeRecognition/index";
import csvUrl from "@/assets/json/community_edges.csv?url";
const keyNodeStore = useKeyNodeRecognitionStore();
const { currentUser } = storeToRefs(keyNodeStore);
const props = defineProps({});
const emit = defineEmits(["click:anchorNode"]);
const teamContainer = ref(null);

//当前在userPanel中选择的某个user
const currentSelectedUser = ref(null);
let chart = null;
//当选中userPanel中的某个用户的时候，更新当前组件的用户
watch(currentUser, (val) => {
  if (val) {
    currentSelectedUser.value = val;
    const option = chart.getOption();

    //实现选中只高亮一个
    chart.dispatchAction({
      //先让所有的先取消高亮
      type: "downplay",
      seriesIndex: 0
    });
    const nodeIndex = option.series[0].data.findIndex((item) =>
      item.anchorList.includes(currentSelectedUser.value.name)
    );
    chart.dispatchAction({
      //再让单独一个高亮
      type: "highlight",
      dataIndex: nodeIndex
    });

    // 2. 平移到节点
  }
});

const initChart = async () => {
  // 初始化图表
  chart = echarts.init(document.getElementById("container"));

  //处理data
  //统计每一个锚点在某些社团，这个社团包含锚点的个数（key: 社团id， value: 这个社团含有几个锚点）
  //统计每个社团包含的锚点id列表
  const anchorCommunityInfo = {};
  Object.entries(anchor).forEach(([anchorId, communityId]) => {
    if (!anchorCommunityInfo[communityId]) {
      //如果该社团不包含锚点
      anchorCommunityInfo[communityId] = []; //就初始化该社团的锚点数组
    }
    anchorCommunityInfo[communityId].push(anchorId); //把这个社团中的所有锚点id存到列表中（处理一对多的关系：一个社团对应多个锚点）
  });

  //包含锚点的社团 （绿色闪烁的节点）
  const includeAnchorCommunity = Object.entries(anchorCommunityInfo).map(
    ([communityId, anchorList]) => ({
      name: parseInt(communityId), // 社团id
      anchorCount: anchorList.length, // 该社团包含锚点的个数
      anchorList: anchorList // 该社团包含的锚点id数组
    })
  );

  // 创建包含锚点的社团名称集合（提高查找效率）
  const includedCommunityId = includeAnchorCommunity.map((node) => node.name.toString());

  //筛选出不包含锚点的社团（不闪烁的蓝色节点）
  const uncontainedAnchorCommunity = Object.keys(community)
    .filter((node) => !includedCommunityId.includes(node))
    .map((node) => ({ name: parseInt(node), anchorCount: 0 }));

  //合并成功后，统一设置id，避免重复id出现导致echarts渲染失败,并且取出每个社团中有多少个节点
  const nodes = includeAnchorCommunity.concat(uncontainedAnchorCommunity).map((node, index) => ({
    id: index,
    total: Object.values(community)[node.name].length,
    category: node.anchorCount > 0 ? 1 : 0, //(1:含有锚点的社团分类，0：不含锚点的社团)
    ...node
  }));

  //处理links
  // 先把csv文件里的数据进行格式化
  let links = [];
  const linksCsv = await fetch(csvUrl);
  const csvText = await linksCsv.text();
  const lines = csvText.split("\n");
  links = lines
    .slice(1)
    .map((line) => {
      if (!line) return null;
      const values = line.split(",");
      return {
        source: parseInt(values[0]),
        target: parseInt(values[1]),
        edge: parseInt(values[2])
      };
    })
    .filter(Boolean);

  const data = { nodes, links };
  console.log(data);

  const categories = [
    { name: "普通社团", category: 0 },
    { name: "含锚点社团", category: 1 }
  ];
  //   // 初始选项
  const option = {
    //图例配置
    legend: [
      {
        data: categories.map((c) => ({
          name: c.name,
          itemStyle: {
            color:
              c.category === 0
                ? new echarts.graphic.LinearGradient(
                    1,
                    0,
                    0,
                    0, // 从左到右渐变（x0=1, x1=0）
                    [
                      { offset: 0, color: "#49c3ed" }, // 起始色（最右）
                      { offset: 0.5, color: "#5fa3e0" }, // 中间色
                      { offset: 1, color: "#7286d4" } // 结束色（最左）
                    ]
                  ) // 分类0的渐变
                : new echarts.graphic.LinearGradient(
                    1,
                    0,
                    0,
                    0, // 从左到右渐变 (x0=1, x1=0)
                    [
                      { offset: 0, color: "#7ff2c1" },
                      { offset: 0.37, color: "#85e7d2" },
                      { offset: 1, color: "#8bdbe4" }
                    ]
                  ) // 分类1的渐变
          }
        })),
        right: 15,
        bottom: 13,
        icon: "circle",
        orient: "vertical",
        itemWidth: 16,
        itemHeight: 16,
        itemGap: 12,
        backgroundColor: "rgba(0,67,125,0.56)", // 半透明深蓝
        borderRadius: 8, // 圆角
        borderColor: "#c2f2ff", // 淡蓝色边框
        borderWidth: 0.3,
        padding: [12, 20, 12, 20], // 上右下左
        textStyle: {
          color: "#fff",
          fontSize: 16,
          fontWeight: "normal"
        }
      }
    ],
    //hover上去的窗口
    tooltip: {
      trigger: "item",
      trigger: "item",
      backgroundColor: "rgba(0,0,0,0)", // 透明背景
      borderColor: "rgba(0,0,0,0)", // 透明边框
      borderWidth: 0,
      extraCssText: "box-shadow:none;padding:0;",
      formatter: function (params) {
        if (params.dataType === "node") {
          return `<div
                    style="
                    width: 107px;
                    height: 68px;
                    border-radius: 4px;
                    background: url('${nodeHoverImg}');
                    background-size: cover;
                    background-position: center;
                    background-repeat: no-repeat;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    flex-direction: column;
                    ">
                <div style="color:#fff;letter-spacing: 0.14px;">
                    <div >节点数：${params.data.total}</div>
                    <div>锚点数：${params.data.anchorCount}</div>
              </div>
            </div>`;
        }
        return "";
      }
    },

    //权值设置样式
    edgeLabel: {
      show: false,
      position: "middle",
      formatter: function (params) {
        return params.data.edge;
      },
      fontSize: 14
    },
    emphasis: {
      edgeLabel: {
        show: true,
        color: "#fff",
        fontSize: 18,
        textShadowColor: "#fff",
        textShadowBlur: 0,
        textShadowOffsetX: 0,
        textShadowOffsetY: 0
      }
    },
    series: [
      {
        type: "graph",
        layout: "force",
        animation: false,
        draggable: true,
        roam: true,
        zoom: 0.4,
        categories: categories,
        force: {
          initLayout: null,
          edgeLength: 1000,
          repulsion: 1000,
          gravity: 0.4,
          friction: 0.6,
          layoutAnimation: true,
          coolingFactor: 0.1
        },

        animationDurationUpdate: 3500, // 节点移动更平滑
        data: data.nodes.map((node) => ({
          ...node,
          symbolSize: node.total / 20 < 30 ? 30 : node.total / 20,
          itemStyle: {
            color: {
              type: "radial",
              x: 0.97,
              y: 0.38,
              r: 0.86,
              colorStops:
                node.anchorCount === 0
                  ? [
                      // anchorCount为0的节点渐变（深蓝到青）
                      { offset: 0, color: "#49c3ed" }, // 最右侧
                      { offset: 0.5, color: "#5fa3e0" }, // 中间
                      { offset: 1, color: "#7286d4" } // 最左侧
                    ]
                  : [
                      // anchorCount为1的节点渐变（原配色）
                      { offset: 0, color: "#7ff2c1" },
                      { offset: 0.37, color: "#85e7d2" },
                      { offset: 1, color: "#8bdbe4" }
                    ]
            },
            opacity: 1,
            borderColor: "#46C6AD",
            borderWidth: 1,
            shadowBlur: 4,
            borderType: "dashed",
            shadowColor: "rgba(19, 27, 114, 0.25)"
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 20,
              shadowColor: "#c4a651",
              borderColor: "#fcd267",
              borderWidth: node.category == 0 ? 1 : 5,
              borderType: "solid"
            }
          }
        })),
        links: data.links,
        lineStyle: {
          color: "#37ACD7",
          width: 1
        }
      }
    ]
  };

  chart.setOption(option);
};

const handleClickNode = () => {
  chart.on("click", function (params) {
    //params.data.name才是社团id
    if (params.dataType === "node" && params.data.category == 1) {
      emit("click:anchorNode", params.data);
    }
  });
};

onMounted(() => {
  initChart();
  handleClickNode();
});
</script>

<style scoped lang="less">
.communityNode-component {
  width: 100%;
  height: 100%;
  .container {
    width: 100%;
    height: 450px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
