<th:block th:fragment="scripts">
  <script>
    document.querySelectorAll(".steam-badge[data-hue]").forEach((badge) => {
      const img = badge.querySelector(".steam-badge__img");
      if (img) return;
      const hue = badge.dataset.hue;
      badge.style.background = `linear-gradient(135deg, hsl(${hue}, 60%, 45%) 0%, hsl(${hue}, 60%, 30%) 100%)`;
      badge.style.borderColor = `hsl(${hue}, 60%, 45%)`;
    });
  </script>

  <script th:if="${showHeatmap}" th:inline="javascript">
    (function () {
      const SteamHeatmap = {
        chart: null,
        chartData: null,
        observer: null,

        config: {
          days: /*[[${heatmapDays}]]*/ 365,
          showLegend: /*[[${heatmapShowLegend}]]*/ true,
        },

        // 获取主题配色 - 根据当前明暗模式返回对应的颜色配置
        getThemeColors: function () {
          const isDark = document.documentElement.classList.contains("dark");
          const primaryHue = 220; // 主题色相 220deg (蓝色)

          if (isDark) {
            // 暗色模式配色
            return {
              empty: "#0d1117",
              colors: [
                `hsl(${primaryHue} 60% 25%)`,
                `hsl(${primaryHue} 70% 35%)`,
                `hsl(${primaryHue} 80% 45%)`,
                `hsl(${primaryHue} 90% 60%)`,
                `hsl(${primaryHue} 100% 70%)`,
              ],
            };
          } else {
            // 亮色模式配色
            return {
              empty: "#f6f8fa",
              colors: [
                `hsl(${primaryHue} 50% 85%)`,
                `hsl(${primaryHue} 60% 70%)`,
                `hsl(${primaryHue} 70% 55%)`,
                `hsl(${primaryHue} 80% 45%)`,
                `hsl(${primaryHue} 90% 35%)`,
              ],
            };
          }
        },

        loadECharts: function () {
          return new Promise((resolve, reject) => {
            if (window.echarts) {
              resolve(window.echarts);
              return;
            }
            const script = document.createElement("script");
            script.src = "https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js";
            script.onload = () => resolve(window.echarts);
            script.onerror = reject;
            document.head.appendChild(script);
          });
        },

        fetchHeatmapData: async function () {
          const endDate = new Date();
          const startDate = new Date();
          startDate.setDate(startDate.getDate() - SteamHeatmap.config.days);

          const formatDate = (date) => {
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, "0");
            const day = String(date.getDate()).padStart(2, "0");
            return `${year}-${month}-${day}`;
          };

          const url = `/apis/api.steam.timxs.com/v1alpha1/heatmap/records?startDate=${formatDate(startDate)}&endDate=${formatDate(endDate)}&page=1&size=${SteamHeatmap.config.days}`;

          const response = await fetch(url);
          if (!response.ok) {
            throw new Error("Failed to fetch heatmap data");
          }
          return await response.json();
        },

        processHeatmapData: function (data) {
          const dateMap = new Map();

          if (data.items && data.items.length > 0) {
            data.items.forEach((record) => {
              const date = record.spec.date;
              const minutes = record.spec.playtimeMinutes || 0;
              dateMap.set(date, (dateMap.get(date) || 0) + minutes);
            });
          }

          const result = [];
          const endDate = new Date();
          const startDate = new Date();
          startDate.setDate(startDate.getDate() - SteamHeatmap.config.days);

          for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
            const dateStr = d.toISOString().split("T")[0];
            const minutes = dateMap.get(dateStr) || 0;
            const hours = (minutes / 60).toFixed(1);
            result.push([dateStr, minutes, hours]);
          }

          return result;
        },

        // 初始化主题模式（浅、暗色）变化监听
        initThemeObserver: function () {
          if (SteamHeatmap.observer) {
            SteamHeatmap.observer.disconnect();
          }

          SteamHeatmap.observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
              if (mutation.type === "attributes" && mutation.attributeName === "class") {
                SteamHeatmap.updateChartTheme();
              }
            });
          });

          SteamHeatmap.observer.observe(document.documentElement, {
            attributes: true,
            attributeFilter: ["class"],
          });
        },

        // 更新热力图（浅色、暗色）主题（不重新获取数据）
        updateChartTheme: function () {
          if (!SteamHeatmap.chart || !SteamHeatmap.chartData) return;

          const themeColors = SteamHeatmap.getThemeColors();
          const colors = themeColors.colors;
          const emptyColor = themeColors.empty;

          const maxMinutes = Math.max(...SteamHeatmap.chartData.map((item) => item[1]), 1);
          const step = maxMinutes / 5;
          const pieces = [
            { min: 0, max: 0, color: emptyColor },
            { gt: 0, lte: step, color: colors[0] },
            { gt: step, lte: step * 2, color: colors[1] },
            { gt: step * 2, lte: step * 3, color: colors[2] },
            { gt: step * 3, lte: step * 4, color: colors[3] },
            { gt: step * 4, color: colors[4] },
          ];

          const isDark = document.documentElement.classList.contains("dark");
          const textColor = isDark ? "#c7d5e0" : "#333";
          const subTextColor = isDark ? "#8f98a0" : "#666";

          SteamHeatmap.chart.setOption({
            tooltip: {
              backgroundColor: isDark ? "rgba(27, 40, 56, 0.95)" : "rgba(255, 255, 255, 0.95)",
              borderColor: isDark ? "#2a475e" : "#e5e7eb",
              textStyle: { color: textColor },
            },
            visualMap: {
              pieces: pieces,
              textStyle: { color: subTextColor },
            },
            calendar: {
              yearLabel: { color: textColor },
              monthLabel: { color: subTextColor },
              dayLabel: { color: subTextColor },
            },
            series: [
              {
                itemStyle: {
                  borderColor: isDark ? "#1b2838" : "#f3f4f6",
                },
              },
            ],
          });

          const legendColorsEl = document.getElementById("heatmap-legend-colors");
          if (legendColorsEl) {
            legendColorsEl.innerHTML = "";

            const emptyBlock = document.createElement("div");
            emptyBlock.className = "steam-heatmap__legend-color";
            emptyBlock.style.backgroundColor = emptyColor;
            legendColorsEl.appendChild(emptyBlock);

            colors.forEach((color) => {
              const colorBlock = document.createElement("div");
              colorBlock.className = "steam-heatmap__legend-color";
              colorBlock.style.backgroundColor = color;
              legendColorsEl.appendChild(colorBlock);
            });
          }
        },

        render: async function () {
          const loadingEl = document.getElementById("heatmap-loading");
          const emptyEl = document.getElementById("heatmap-empty");
          const errorEl = document.getElementById("heatmap-error");
          const chartEl = document.getElementById("heatmap-chart");

          if (!chartEl) return;

          // 清理旧的图表实例和监听器
          if (SteamHeatmap.chart) {
            SteamHeatmap.chart.dispose();
            SteamHeatmap.chart = null;
          }
          if (SteamHeatmap.observer) {
            SteamHeatmap.observer.disconnect();
            SteamHeatmap.observer = null;
          }

          try {
            const echarts = await SteamHeatmap.loadECharts();
            const data = await SteamHeatmap.fetchHeatmapData();
            SteamHeatmap.chartData = SteamHeatmap.processHeatmapData(data);

            loadingEl.style.display = "none";
            chartEl.style.display = "block";

            SteamHeatmap.chart = echarts.init(chartEl);

            // 初始化主题监听
            SteamHeatmap.initThemeObserver();
            const themeColors = SteamHeatmap.getThemeColors();
            const colors = themeColors.colors;
            const emptyColor = themeColors.empty;

            const maxMinutes = Math.max(...SteamHeatmap.chartData.map((item) => item[1]), 1);
            const step = maxMinutes / 5;
            const pieces = [
              { min: 0, max: 0, color: emptyColor },
              { gt: 0, lte: step, color: colors[0] },
              { gt: step, lte: step * 2, color: colors[1] },
              { gt: step * 2, lte: step * 3, color: colors[2] },
              { gt: step * 3, lte: step * 4, color: colors[3] },
              { gt: step * 4, color: colors[4] },
            ];

            const isDark = document.documentElement.classList.contains("dark");
            const textColor = isDark ? "#c7d5e0" : "#333";
            const subTextColor = isDark ? "#8f98a0" : "#666";

            const option = {
              tooltip: {
                position: "top",
                formatter: function (params) {
                  const date = params.data[0];
                  const hours = params.data[2];
                  return `${date}<br/>游戏时长: ${hours} 小时`;
                },
                backgroundColor: isDark ? "rgba(27, 40, 56, 0.95)" : "rgba(255, 255, 255, 0.95)",
                borderColor: isDark ? "#2a475e" : "#e5e7eb",
                textStyle: { color: textColor },
              },
              visualMap: SteamHeatmap.config.showLegend
                ? {
                    show: true,
                    type: "piecewise",
                    pieces: pieces,
                    orient: "horizontal",
                    left: "center",
                    bottom: "0",
                    text: ["高", "低"],
                    textStyle: { color: subTextColor },
                    itemWidth: 10,
                    itemHeight: 10,
                  }
                : {
                    show: false,
                    type: "piecewise",
                    pieces: pieces,
                  },
              calendar: {
                top: 20,
                left: 30,
                right: 30,
                bottom: SteamHeatmap.config.showLegend ? 40 : 20,
                range: [SteamHeatmap.chartData[0][0], SteamHeatmap.chartData[SteamHeatmap.chartData.length - 1][0]],
                cellSize: ["auto", 13],
                splitLine: { show: false },
                itemStyle: {
                  borderColor: "transparent",
                  borderWidth: 0,
                },
                yearLabel: { show: true, color: textColor },
                monthLabel: { show: true, color: subTextColor, nameMap: "ZH" },
                dayLabel: { show: true, color: subTextColor, nameMap: "ZH", firstDay: 1 },
              },
              series: [
                {
                  type: "heatmap",
                  coordinateSystem: "calendar",
                  data: SteamHeatmap.chartData,
                  itemStyle: {
                    borderColor: isDark ? "#1b2838" : "#f3f4f6",
                    borderWidth: 2,
                    borderRadius: 2,
                  },
                },
              ],
            };

            SteamHeatmap.chart.setOption(option);

            const legendEl = document.getElementById("heatmap-legend");
            const legendColorsEl = document.getElementById("heatmap-legend-colors");
            legendColorsEl.innerHTML = "";

            const emptyBlock = document.createElement("div");
            emptyBlock.className = "steam-heatmap__legend-color";
            emptyBlock.style.backgroundColor = emptyColor;
            legendColorsEl.appendChild(emptyBlock);

            colors.forEach((color) => {
              const colorBlock = document.createElement("div");
              colorBlock.className = "steam-heatmap__legend-color";
              colorBlock.style.backgroundColor = color;
              legendColorsEl.appendChild(colorBlock);
            });

            legendEl.style.display = "flex";

            window.addEventListener("resize", () => {
              SteamHeatmap.chart.resize();
            });
          } catch (error) {
            console.error("Failed to render heatmap:", error);
            loadingEl.style.display = "none";
            errorEl.style.display = "flex";
          }
        },
      };

      if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", SteamHeatmap.render);
      } else {
        SteamHeatmap.render();
      }
    })();
  </script>
</th:block>
