<script setup>
// Tab 切換仍然緩慢 → 加上「快取 + 動畫關閉 + 更小抽樣 + 輕量 setOption」
// 1) 先用快取立即顯示，再背景刷新（體感超快）。
// 2) 關閉 ECharts 動畫、縮短 update 動畫時間，減少重排成本。
// 3) 抽樣點從 30 → 20，計算更輕。
// 4) Tab 切換不重啟輪詢，避免重設計時器造成 jank。

import LineChart from "@/components/chart/LineChart.vue";
import { SECOND_CHART_COLOR } from "@/constant";
import dayjs from "dayjs";
import { ref, watch, onUnmounted, computed, nextTick } from "vue";
import useActiveBtn from "@/hooks/useActiveBtn";
import { getDashboardTemp } from "@/apis/dashboard";
import useBuildingStore from "@/stores/useBuildingStore";
import { useI18n } from "vue-i18n";

const { t, locale } = useI18n();
const buildingStore = useBuildingStore();

// --- UI：溫/濕度切換狀態 ---
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
const currentOptionType = ref(1); // 1 = 溫度、2 = 濕度

// --- 資料與顯示控制 ---
const allTempData = ref([]);
const noData = ref(false);
const indoorChartRef = ref(null);

// --- 計時器與請求序列控制 ---
const POLL_MS = 60000; // 每 60 秒輪詢
const timeoutTimer = ref(null);
let lastAcceptedSeq = 0; // 最新被接受的請求序號
let seqCounter = 0; // 連增序號，避免併發覆蓋

function clearPolling() {
  if (timeoutTimer.value) {
    clearInterval(timeoutTimer.value);
    timeoutTimer.value = null;
  }
}
function startPolling() {
  if (timeoutTimer.value) return; // 不要重複啟動
  timeoutTimer.value = setInterval(() => safeGetData(false), POLL_MS);
}

// --- 簡易快取（大樓 + 類型） ---
const cache = new Map();
const cacheKey = (guid, opt) => `${guid}__${opt}`;
function writeCache(guid, opt, data) {
  cache.set(cacheKey(guid, opt), data);
}
function readCache(guid, opt) {
  return cache.get(cacheKey(guid, opt));
}

// 只接受最後一筆回應的取數封裝（並寫入快取）
async function safeGetData(force = true) {
  const buildingGuid = buildingStore.selectedBuilding?.building_guid;
  if (!buildingGuid) return;

  const mySeq = ++seqCounter; // 本次請求的序號

  try {
    const res = await getDashboardTemp({
      building_guid: buildingGuid,
      tempOption: 1, // 室溫區域
      timeInterval: 1,
      option: currentOptionType.value,
    });

    if (mySeq < lastAcceptedSeq) return; // 舊回應丟棄
    lastAcceptedSeq = mySeq;

    const key = "室溫";
    const data = res?.isSuccess ? res.data?.[key] ?? [] : [];

    allTempData.value = data;
    noData.value = data.length === 0;

    writeCache(buildingGuid, currentOptionType.value, data);
  } catch (err) {
    if (mySeq < lastAcceptedSeq) return; // 舊錯誤丟棄
    console.error("getDashboardTemp error", err);
    allTempData.value = [];
    noData.value = true;
  }
}

// 預設圖表設定：關閉動畫以縮短切換延遲
const defaultChartOption = ref({
  animation: false,
  animationDuration: 0,
  animationDurationUpdate: 150,
  animationEasingUpdate: "linear",
  tooltip: { trigger: "axis" },
  legend: {
    data: [],
    top: 0,
    textStyle: { color: "#ffffff", fontSize: 12 },
  },
  grid: {
    top: "35%",
    left: "0%",
    right: "0%",
    bottom: "0%",
    containLabel: true,
  },
  xAxis: {
    type: "category",
    splitLine: { show: false },
    axisLabel: { color: "#ffffff" },
    data: [],
  },
  yAxis: {
    type: "value",
    splitLine: { show: false },
    axisLabel: { color: "#ffffff" },
  },
  series: [],
});

// 設定資料點顯示數量（更小抽樣，預設 20）
function sampleData(data = [], maxCount = 20) {
  const len = data.length;
  if (len <= maxCount) return data;
  const sampled = [];
  const step = (len - 1) / (maxCount - 1);
  for (let i = 0; i < maxCount; i++) {
    const index = Math.round(i * step);
    sampled.push(data[index]);
  }
  return sampled;
}

// 多語系切換時更新按鈕文字
const buttonItems = computed(() => [
  { key: 1, title: t("dashboard.temperature"), active: true },
  { key: 2, title: t("dashboard.humidity"), active: false },
]);

watch(
  () => locale.value,
  () => setItems(buttonItems.value),
  { immediate: true }
);

// 切換溫/濕度：
// 1) 先讀快取直接畫（立即回饋）
// 2) 再觸發安全取數刷新
watch(
  () => selectedBtn.value?.key,
  async (key) => {
    if (!(key === 1 || key === 2)) return;
    currentOptionType.value = key;

    const guid = buildingStore.selectedBuilding?.building_guid;
    if (!guid || buildingStore.sysConfig?.value?.show_room === false) return;

    const cached = readCache(guid, key);
    if (cached) {
      allTempData.value = cached;
      noData.value = cached.length === 0;
      // 用 nextTick 確保 DOM/Chart 就緒再 setOption（體感更順）
      await nextTick();
      applyToChart(cached);
    }

    // 背景刷新最新資料（回來後仍會覆蓋）
    safeGetData(false);
    // ⚠ 不重啟輪詢，避免 timer 抖動
  },
  { immediate: true }
);

// 監看建築切換：統一流程（取消舊輪詢 → 讀取配置 → 先用快取 → 再取數 → 啟動輪詢）
watch(
  () => buildingStore.selectedBuilding?.building_guid,
  async (guid) => {
    if (!guid) return;

    clearPolling();
    lastAcceptedSeq = 0;
    seqCounter = 0;

    await buildingStore.getSysConfig(guid);
    const showRoom = buildingStore.sysConfig?.value?.show_room;

    if (showRoom === false) {
      noData.value = true;
      return; // 不取資料、不顯示圖
    }

    noData.value = false;

    const cached = readCache(guid, currentOptionType.value);
    if (cached) {
      allTempData.value = cached;
      noData.value = cached.length === 0;
      await nextTick();
      applyToChart(cached);
    }

    await safeGetData();
    startPolling();
  },
  { immediate: true }
);

// 將資料套到圖表（輕量 setOption，關閉動畫）
function applyToChart(newVal) {
  const chart = indoorChartRef.value?.chart;
  if (!chart || !newVal?.length) return;

  const firstValid = newVal.find((d) => d.data?.length);
  if (!firstValid) return;

  const sampledXAxis = sampleData(firstValid.data).map(({ time }) =>
    dayjs(time).format("HH:mm:ss")
  );

  const series = newVal.map((d, i) => ({
    name: d.full_name,
    type: "line",
    data: sampleData(d.data).map(({ value }) => value),
    showSymbol: false,
    // 關閉單序列動畫
    animation: false,
    itemStyle: { color: SECOND_CHART_COLOR[i % SECOND_CHART_COLOR.length] },
  }));

  const vals = series.flatMap((s) => s.data).filter((v) => v != null);
  if (!vals.length) return;

  chart.setOption(
    {
      animation: false,
      animationDurationUpdate: 150,
      animationEasingUpdate: "linear",
      legend: { data: newVal.map((d) => d.full_name) },
      xAxis: { data: sampledXAxis },
      yAxis: {
        min: Math.floor(Math.min(...vals)) - 1,
        max: Math.ceil(Math.max(...vals)) + 1,
      },
      series,
    },
    false,
    true
  );
}

// 資料變動 → 更新圖表（不 deep）
watch(allTempData, (newVal) => {
  applyToChart(newVal);
});

onUnmounted(() => {
  clearPolling();
});
</script>

<template>
  <h3 class="text-info text-xl text-center">
    {{ $t("dashboard.indoor_chart") }}
  </h3>

  <div class="w-full flex justify-center items-center relative">
    <ButtonConnectedGroup
      :items="items"
      :onclick="(e, item) => changeActiveBtn(item)"
    />
  </div>

  <div
    v-if="noData"
    class="text-center text-white text-lg min-h-[260px] flex items-center justify-center"
  >
    {{ $t("dashboard.no_data") }}
  </div>

  <LineChart
    v-if="!noData"
    id="dashboard_other_real_temp"
    class="min-h-[260px] max-h-fit"
    :option="defaultChartOption"
    ref="indoorChartRef"
  />
</template>

<style lang="scss" scoped></style>
