<template>
  <div>
    <!-- 1. 顶部介绍图片 -->
    <div>
      <img src="@/assets/images/instruction.png" alt="系统介绍" class="intruduction" />
    </div>

    <!-- 2. 第一行布局容器 (布局不变) -->
    <div class="leader-containner1">
      <!-- 区域1: 意见领袖列表 -->
      <div class="left-panel">
        <h2 class="panel-title">意见领袖抽展示</h2>
        <div class="tabs">
          <button
            v-for="tab in tabs"
            :key="tab"
            :class="{ active: activeTab === tab }"
            @click="activeTab = tab"
          >
            {{ tab }}
          </button>
        </div>
        <div class="leader-list">
          <div v-for="leader in filteredVisibleLeaders" :key="leader.id" class="leader-item">
            <img :src="leader.avatar" :alt="leader.name" class="avatar" />
            <div class="info">
              <div class="name">
                <span class="en-name">{{ leader.name }}</span>
                <span v-if="leader.chineseName" class="cn-name">{{ leader.chineseName }}</span>
              </div>
              <div class="stats">
                <span>粉丝数量: {{ leader.followers }}</span>
                <span>发帖总数: {{ leader.posts }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 区域2: 佩洛西图谱 (视觉效果已更新) -->
      <div class="right-panel">
        <div class="key-node-recognition">
          <div class="background-svg-wrapper">
            <svg
              width="100%"
              height="100%"
              viewBox="0 0 800 540"
              preserveAspectRatio="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <defs>
                <linearGradient
                  id="paint0_linear_bg"
                  x1="0"
                  y1="167.1"
                  x2="800"
                  y2="167.1"
                  gradientUnits="userSpaceOnUse"
                >
                  <stop stop-color="#063D71" stop-opacity="0.2" />
                  <stop offset="1" stop-color="#081E38" stop-opacity="0.8" />
                </linearGradient>
                <linearGradient
                  id="paint1_linear_border"
                  x1="400"
                  y1="0"
                  x2="400"
                  y2="540"
                  gradientUnits="userSpaceOnUse"
                >
                  <stop stop-color="#3AA1F8" />
                  <stop offset="1" stop-color="#3AA1F8" stop-opacity="0.2" />
                </linearGradient>
              </defs>
              <path
                d="M798 0.5H2C1.17159 0.5 0.500003 1.17158 0.5 2V538C0.5 538.828 1.17159 539.5 2 539.5H798C798.828 539.5 799.5 538.828 799.5 538V2C799.5 1.17157 798.828 0.5 798 0.5Z"
                fill="url(#paint0_linear_bg)"
                fill-opacity="0.48"
                stroke="url(#paint1_linear_border)"
              />
            </svg>
          </div>
          <div class="content-wrapper">
            <h1 class="graph-title">佩洛西系列事件</h1>
            <div ref="chartContainer" class="chart-container"></div>
            <div class="timeline-container">
              <span class="time-label">2022.07.31 00:00:00</span>
              <div class="timeline-track">
                <div
                  v-for="point in timePoints"
                  :key="point.id"
                  class="timeline-point-wrapper"
                  @click="onTimePointClick(point.id)"
                >
                  <div class="timeline-point" :class="{ active: activeTimePoint === point.id }">
                    <div v-if="activeTimePoint === point.id" class="active-pin"></div>
                  </div>
                </div>
              </div>
              <span class="time-label">2022.08.01 00:00:00</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 区域3: 领袖分析 -->
      <LeaderAnalysis :chart-data="analysisChartData" />
    </div>

    <!-- 第二行布局容器 (布局不变) -->
    <div class="leader-containner2">
      <EventHeatmap @show-details="openDetailsModal" />
      <PostDynamics />
      <WordCloud :word-data="wordCloudData" />
    </div>

    <!-- 详情弹窗 -->
    <div v-if="showDetailsModal" class="modal-overlay" @click="closeDetailsModal">
      <div class="modal-content" @click.stop>
        <button class="close-btn" @click="closeDetailsModal">×</button>
        <div ref="detailsChart" class="details-chart-container"></div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick, computed, watch } from "vue";
import * as echarts from "echarts/core";
import { GraphChart } from "echarts/charts";
import { TitleComponent, TooltipComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
import { SVGRenderer } from "echarts/renderers";
import { cropImageToCircle } from "@/utils/transform";
echarts.use([TitleComponent, TooltipComponent, GraphChart, SVGRenderer]);
const allGraphNodes = ref([]);
// 引入其他子组件
import LeaderAnalysis from "./KeyNodeRecognition1/LeaderAnalysis.vue";
import EventHeatmap from "./KeyNodeRecognition1/EventHeatmap.vue";
import PostDynamics from "./KeyNodeRecognition1/PostDynamics.vue";
import WordCloud from "./KeyNodeRecognition1/WordCloud.vue";

// ===================================================================
// 核心状态与数据
// ===================================================================
const activeTimePoint = ref(1);
const timePoints = ref(Array.from({ length: 10 }, (_, i) => ({ id: i + 1 })));

// [更新] 替换为新的10人意见领袖数据，并格式化
const allLeaderData = ref([
  {
    id: "Israel Defense Forces",
    name: "Israel Defense Forces",
    chineseName: null,
    followers: "299.8万",
    posts: "2.4万",
    avatar: new URL("@/assets/images/Israel.png", import.meta.url).toString(),
    category: "政府官号"
  },
  {
    id: "Emmanuel Macron",
    name: "Emmanuel Macron",
    chineseName: null,
    followers: "1018.6万",
    posts: "1.4万",
    avatar: new URL("@/assets/images/Emmanuel.png", import.meta.url).toString(),
    category: "政府官号"
  },
  {
    id: "President Biden Archived",
    name: "President Biden Archived",
    chineseName: null,
    followers: "3670.7万",
    posts: "1万",
    avatar: new URL("@/assets/images/Biden.png", import.meta.url).toString(),
    category: "政府官号"
  },
  {
    id: "Secretary Antony Blinken",
    name: "Secretary Antony Blinken",
    chineseName: null,
    followers: "223万",
    posts: "6082",
    avatar: new URL("@/assets/images/Antony.png", import.meta.url).toString(),
    category: "政府官号"
  },
  {
    id: "Paul Golding",
    name: "Paul Golding",
    chineseName: null,
    followers: "27万",
    posts: "4.1万",
    avatar: new URL("@/assets/images/Golding.png", import.meta.url).toString(),
    category: "政府官号"
  },
  {
    id: "Andy Ngo",
    name: "Andy Ngo",
    chineseName: null,
    followers: "167.8万",
    posts: "5.5万",
    avatar: new URL("@/assets/images/Andy.png", import.meta.url).toString(),
    category: "自媒体"
  },
  {
    id: "Joe Truzman",
    name: "Joe Truzman",
    chineseName: null,
    followers: "11.4万",
    posts: "3.8万",
    avatar: new URL("@/assets/images/Truzman.png", import.meta.url).toString(),
    category: "自媒体"
  },
  {
    id: "Jackson Hinkle 🇺🇸",
    name: "Jackson Hinkle 🇺🇸",
    chineseName: null,
    followers: "304.9万",
    posts: "2.9万",
    avatar: new URL("@/assets/images/Jackson.png", import.meta.url).toString(),
    category: "自媒体"
  },
  {
    id: "Rep. Matt Gaetz",
    name: "Rep. Matt Gaetz",
    chineseName: null,
    followers: "316.4万",
    posts: "1.4万",
    avatar: new URL("@/assets/images/Matt.png", import.meta.url).toString(),
    category: "自媒体"
  },
  {
    id: "OSINTdefender",
    name: "OSINTdefender",
    chineseName: null,
    followers: "133.5万",
    posts: "4.8万",
    avatar: new URL("@/assets/images/OSINTdefender.png", import.meta.url).toString(),
    category: "新闻媒体"
  }
]);

// [更新] 为新的10位领袖定义固定坐标
const nodeCoordinates = {
  reuters: { x: 150, y: 150 },
  spectator: { x: 350, y: 350 },
  indopacific: { x: 600, y: 450 },
  liuxiaoming: { x: 400, y: 120 },
  huxijin: { x: 200, y: 500 },
  mickwallace: { x: 480, y: 550 },
  jiushiniya: { x: 650, y: 180 },
  levi_godman: { x: 850, y: 250 },
  bidishalolo: { x: 800, y: 500 },
  indobosss: { x: 600, y: 600 }
};

const visibleLeaders = computed(() => allLeaderData.value.slice(0, activeTimePoint.value));

const tabs = ref(["全部", "新闻媒体", "自媒体", "政府官号"]);
const activeTab = ref("全部");
const filteredVisibleLeaders = computed(() => {
  if (activeTab.value === "全部") return visibleLeaders.value;
  return visibleLeaders.value.filter((leader) => leader.category === activeTab.value);
});

// 右侧图谱逻辑
const chartContainer = ref(null);
let myChart = null;
const chartOptions = {
  tooltip: {},
  animationDurationUpdate: 1500,
  animationEasingUpdate: "quinticInOut",
  series: [
    {
      type: "graph",
      layout: "none",
      roam: true,
      symbolSize: 50,
      label: { show: false },
      edgeSymbol: ["none", "none"],
      symbolClip: true, // 确保全局启用
      symbolKeepAspect: true, // 保持宽高比
      edgeSymbolSize: [4, 10],
      lineStyle: { width: 1, color: "rgba(0, 191, 255, 0.4)", opacity: 0.9 },
      categories: [
        {
          name: "Leader",
          symbolSize: 50,
          itemStyle: {
            borderColor: "rgba(0, 191, 255, 0.8)",
            borderWidth: 3,
            shadowBlur: 15,
            shadowColor: "rgba(0, 10, 255, 0.7)"
          }
        },
        {
          name: "User",
          symbolSize: 25,
          itemStyle: {
            color: "#006A92",
            borderColor: "#00BFFF",
            borderWidth: 2,
            shadowBlur: 5,
            shadowColor: "rgba(0, 191, 255, 0.5)"
          }
        }
      ],
      data: [],
      links: []
    }
  ]
};

const formatAllGraphNodes = async () => {
  const tempResLeaderData = await Promise.all(
    allLeaderData.value.map(async (leader) => {
      const coords = nodeCoordinates[leader.id] || {
        x: Math.random() * 1000,
        y: Math.random() * 600
      };
      const base64_res = await cropImageToCircle(leader.avatar, 50);
      const node = {
        id: leader.id,
        name: leader.name,
        symbol: `image://${base64_res}`,
        category: 0,
        ...coords
      };
      if (leader.id === "mickwallace") {
        node.itemStyle = {
          borderColor: "rgba(255, 220, 0, 0.9)",
          shadowColor: "rgba(255, 220, 0, 0.8)",
          shadowBlur: 20
        };
      }
      return node;
    })
  );
  const userNodes = Array.from({ length: 40 }, (_, i) => ({
    id: `user_${i}`,
    name: `User ${i}`,
    x: Math.random() * 1000,
    y: Math.random() * 600,
    category: 1
  }));
  allGraphNodes.value = [...tempResLeaderData, ...userNodes];
};

const allGraphLinks = computed(() => {
  const leaders = allGraphNodes.value.filter((node) => node.category === 0);
  const users = allGraphNodes.value.filter((node) => node.category === 1);
  const randomLinks = [];
  leaders.forEach((leader) => {
    // 随机打乱用户数组
    const shuffled = users.slice().sort(() => Math.random() - 0.5);
    // 取前三个用户
    shuffled.slice(0, 3).forEach((user) => {
      randomLinks.push({
        source: leader.id,
        target: user.id
      });
    });
  });
  return randomLinks;
});

// ===================================================================
// 核心交互逻辑
// ===================================================================
const onTimePointClick = (pointId) => {
  activeTimePoint.value = pointId;
};

const updateGraphData = (currentVisibleLeaders) => {
  if (!myChart) return;
  const leadersSet = new Set(currentVisibleLeaders.map((l) => l.id));
  const visibleNodes = allGraphNodes.value.filter(
    (node) => node.category === 1 || leadersSet.has(node.id)
  );
  const nodeIds = new Set(visibleNodes.map((n) => n.id));
  const visibleLinks = allGraphLinks.value.filter(
    (link) => nodeIds.has(link.source) && nodeIds.has(link.target)
  );
  myChart.setOption({ series: [{ data: visibleNodes, links: visibleLinks }] });
};

watch(
  visibleLeaders,
  (newVisibleLeaders) => {
    if (myChart) {
      updateGraphData(newVisibleLeaders);
    }
  },
  { deep: true, immediate: true }
);

// ===================================================================
// 其他组件的数据和逻辑
// ===================================================================
const analysisChartData = ref([
  {
    title: "平均发帖数",
    unit: "数量",
    max: 10,
    series: [
      { name: "领袖", value: 6.4 },
      { name: "所有用户", value: 0.46 }
    ]
  },
  {
    title: "帖子平均生存周期",
    unit: "天数",
    max: 10,
    series: [
      { name: "领袖", value: 2.19 },
      { name: "所有用户", value: 0.46 }
    ]
  },
  {
    title: "平均粉丝数",
    unit: "天数",
    max: 10,
    series: [
      { name: "领袖", value: 2.19 },
      { name: "所有用户", value: 0.46 }
    ]
  }
]);
const wordCloudData = ref([
  { text: "佩洛西", size: "large", color: "#56a9de", top: "28%", left: "70%" },
  { text: "中国", size: "large", color: "#56a9de", top: "70%", left: "22%" },
  { text: "中国人民解放军", size: "medium", color: "#cdeeff", top: "15%", left: "40%" },
  { text: "中美关系", size: "medium", color: "#cdeeff", top: "50%", left: "60%" },
  { text: "台海和平", size: "medium", color: "#27c1a8", top: "80%", left: "65%" }
]);
const showDetailsModal = ref(false);
const detailsChart = ref(null);
let myDetailsChart = null;
const openDetailsModal = (chartConfig) => {
  showDetailsModal.value = true;
  nextTick(() => {
    if (detailsChart.value) {
      myDetailsChart = echarts.init(detailsChart.value);
      myDetailsChart.setOption(chartConfig.option);
    }
  });
};
const closeDetailsModal = () => {
  showDetailsModal.value = false;
  if (myDetailsChart) {
    myDetailsChart.dispose();
    myDetailsChart = null;
  }
};
//页面启动自动播放
let timer = null;
const automaticPlay = () => {
  let index = 1;
  if (timer) clearInterval(timer);
  timer = setInterval(() => {
    onTimePointClick(index);
    if (index == allLeaderData.value.length) {
      clearInterval(timer);
      timer = null;
      return;
    }
    index++;
  }, 1500);
};
//点击任意一个leader节点出现弹框
const monitoringNode = (myChart) => {
  myChart.on("click", (params) => {
    // 判断是否点击的是领导节点
    if (params.data && params.data.category === 0) {
      console.log(params);
    }
  });
};
// ===================================================================
// 生命周期钩子
// ===================================================================
onMounted(async () => {
  await formatAllGraphNodes();
  if (chartContainer.value) {
    myChart = echarts.init(chartContainer.value, null, { renderer: "svg" });
    //只保留名为 "Hu Xijin" 的领导节点，用户节点不变
    const firstData = allGraphNodes.value.filter(
      (item) =>
        (item.name === "Israel Defense Forces" && item.category === 0) || item.category === 1
    );
    myChart.setOption({
      ...chartOptions,
      series: [
        {
          ...chartOptions.series[0],
          data: firstData,
          links: allGraphLinks.value
        }
      ]
    });
    window.addEventListener("resize", myChart.resize);
  }
  monitoringNode(myChart);
  automaticPlay();
});

onUnmounted(() => {
  if (myChart) {
    window.removeEventListener("resize", myChart.resize);
    myChart.dispose();
  }
  if (myDetailsChart) {
    myDetailsChart.dispose();
  }
});
</script>

<style scoped>
.intruduction {
  width: 100%;
  margin-top: 0px;
  border-radius: 2px;
}
.leader-containner1,
.leader-containner2 {
  display: flex;
  flex-direction: row;
  gap: 10px;
}
.leader-containner2 {
  margin-top: 10px;
}
.left-panel {
  width: 350px;
  flex-shrink: 0;
  background-color: rgba(6, 45, 90, 0.3);
  border: 1px solid #1a8bff;
  display: flex;
  flex-direction: column;
  padding: 15px;
}
.panel-title {
  font-size: 18px;
  font-weight: bold;
  text-align: center;
  padding: 10px;
  margin: 0 0 15px 0;
  background: linear-gradient(
    to right,
    rgba(58, 161, 248, 0),
    rgba(58, 161, 248, 0.3),
    rgba(58, 161, 248, 0)
  );
  border-top: 1px solid #3aa1f8;
  border-bottom: 1px solid #3aa1f8;
  color: #fff;
}
.tabs {
  display: flex;
  margin-bottom: 15px;
  border-bottom: 2px solid #1a5a9c;
}
.tabs button {
  background: none;
  border: none;
  color: #a9c2e0;
  padding: 8px 16px;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
}
.tabs button.active {
  color: #fff;
  font-weight: bold;
}
.tabs button.active::after {
  content: "";
  position: absolute;
  bottom: -2px;
  left: 0;
  width: 100%;
  height: 2px;
  background-color: #3aa1f8;
}
.leader-list {
  width: 100%;
  height: 410px;
  flex-grow: 1;
  overflow: auto;
  scrollbar-width: none;
  color: #fff;
}
.leader-list::-webkit-scrollbar {
  width: 4px;
}
.leader-list::-webkit-scrollbar-track {
  background: transparent;
}
.leader-list::-webkit-scrollbar-thumb {
  background: #3aa1f8;
  border-radius: 2px;
}
.leader-item {
  display: flex;
  align-items: center;
  padding: 10px 5px;
  border-bottom: 1px solid rgba(58, 161, 248, 0.2);
}
.avatar {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  margin-right: 15px;
  flex-shrink: 0;
}
.info {
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.name {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.en-name {
  font-size: 16px;
  font-weight: bold;
}
.cn-name {
  font-size: 14px;
  color: #a9c2e0;
}
.stats {
  font-size: 12px;
  color: #a9c2e0;
  display: flex;
  gap: 20px;
}
.right-panel {
  flex-grow: 1;
  position: relative;
}
.key-node-recognition {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.background-svg-wrapper {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}
.content-wrapper {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 15px 20px;
  box-sizing: border-box;
}
.graph-title {
  text-align: center;
  font-size: 20px;
  font-weight: bold;
  color: #cce7ff;
  letter-spacing: 2px;
  margin: 0 0 5px 0;
  text-shadow: 0 0 5px rgba(58, 161, 248, 0.5);
}
.chart-container {
  flex-grow: 1;
  width: 100%;
  height: calc(100% - 100px);
}
.timeline-container {
  width: 100%;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 10px;
  box-sizing: border-box;
}
.time-label {
  font-size: 12px;
  color: #a9c2e0;
}
.timeline-track {
  flex-grow: 1;
  height: 4px;
  background: linear-gradient(90deg, #1b62a9, #3aa1f8, #1b62a9);
  margin: 0 15px;
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.timeline-point-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 20px;
  cursor: pointer;
}
.timeline-point {
  width: 10px;
  height: 10px;
  background-color: #8dc5ff;
  border-radius: 50%;
  border: 1px solid #cce7ff;
  transition: transform 0.3s ease;
  position: relative;
}
.timeline-point-wrapper:hover .timeline-point {
  transform: scale(1.5);
}
.timeline-point.active {
  background-color: #ffc94d;
  border-color: #fff;
  transform: scale(1.3);
}
.active-pin {
  width: 20px;
  height: 24px;
  background-image: url('data:image/svg+xml;utf8,<svg width="20" height="24" viewBox="0 0 20 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M10 24L15 14H5L10 24Z" fill="%23FFC94D"/><path d="M1.5 8C1.5 4.41015 4.41015 1.5 8 1.5H12C15.5899 1.5 18.5 4.41015 18.5 8V11C18.5 12.6569 17.1569 14 15.5 14H4.5C2.84315 14 1.5 12.6569 1.5 11V8Z" fill="%23FFC94D" stroke="white"/></svg>');
  position: absolute;
  bottom: 5px;
  left: 50%;
  transform: translateX(-50%);
}
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}
.modal-content {
  position: relative;
  background-color: #0d1b38;
  padding: 20px;
  border-radius: 8px;
  border: 1px solid #3a95ff;
  box-shadow: 0 0 25px rgba(58, 149, 255, 0.5);
  width: 50vw;
  height: 45vh;
  display: flex;
  flex-direction: column;
}
.close-btn {
  position: absolute;
  width: 20px;
  height: 20px;

  display: flex;
  align-items: center;
  justify-content: center;
  top: 10px;
  right: 15px;
  border: none;
  color: #a7c5d4;
  background: none;
  font-size: 24px;
  cursor: pointer;
}
.details-chart-container {
  width: 100%;
  flex-grow: 1;
}
</style>
