(() => {
  const root = document.querySelector("[data-dashboard-metrics]");
  if (!root) return;
  const memoryChart = root.querySelector("[data-memory-chart]");
  const logChart = root.querySelector("[data-log-chart]");
  const logSummary = root.querySelector("[data-log-summary]");
  const status = root.querySelector("[data-metrics-status]");
  const memoryScopeLabel = root.querySelector("[data-memory-scope-label]");
  const logScopeLabel = root.querySelector("[data-log-scope-label]");
  const scopeButtons = Array.from(root.querySelectorAll("[data-dashboard-scope]"));
  let activeScope = window.localStorage.getItem("lumi-dashboard-scope") || "5m";

  const scopeLabels = { "5m": "5 minutes", "24h": "24 hours", "7d": "7 days" };
  const levels = [
    ["error", "Errors", "danger"],
    ["warn", "Warnings", "warning"],
    ["info", "Info", "info"],
    ["debug", "Debug", "text-muted"]
  ];

  const bytes = (value) => {
    const mb = Number(value || 0) / 1048576;
    return mb >= 1024 ? `${(mb / 1024).toFixed(1)} GB` : `${mb.toFixed(0)} MB`;
  };

  const duration = (seconds) => {
    const total = Number(seconds || 0);
    const hours = Math.floor(total / 3600);
    const minutes = Math.floor((total % 3600) / 60);
    return hours ? `${hours}h ${minutes}m` : `${minutes}m`;
  };

  const setMetric = (name, value) => {
    const target = root.querySelector(`[data-metric="${name}"]`);
    if (target) target.textContent = value;
  };

  const escapeAttr = (value) => String(value ?? "").replace(/[&"<]/g, (char) => ({
    "&": "&amp;",
    "\"": "&quot;",
    "<": "&lt;"
  })[char]);

  const scaleX = (sample, samples, scopeMs, now) => {
    if (samples.length <= 1) return 290;
    const min = now - scopeMs;
    return 10 + Math.max(0, Math.min(1, (sample.sampled_at - min) / scopeMs)) * 250;
  };

  const scaleY = (value, max) => 104 - (Number(value || 0) / Math.max(max, 1)) * 82;

  const drawMemory = (data) => {
    if (!memoryChart) return;
    const samples = data.memory_scopes?.[activeScope] || [];
    const scopeMs = data.scopes?.[activeScope]?.duration_ms || 5 * 60 * 1000;
    const now = Number(data.sampled_at || Date.now());
    const max = Math.max(...samples.map((sample) => sample.rss), data.memory?.rss || 0, 1);
    const gridValues = [0, 0.25, 0.5, 0.75, 1].map((ratio) => Math.round(max * ratio));
    const points = samples.map((sample) => `${scaleX(sample, samples, scopeMs, now).toFixed(1)},${scaleY(sample.rss, max).toFixed(1)}`).join(" ");
    const labelSamples = samples.length <= 3
      ? samples
      : [samples[0], samples[Math.floor(samples.length / 2)], samples[samples.length - 1]];
    const grid = gridValues.map((value) => {
      const y = scaleY(value, max);
      return `<line x1="10" x2="285" y1="${y.toFixed(1)}" y2="${y.toFixed(1)}" stroke="var(--lumi-border)" stroke-width="1"></line><text x="288" y="${(y + 3).toFixed(1)}" fill="var(--lumi-text-muted)" font-size="8">${bytes(value)}</text>`;
    }).join("");
    const vertical = [0, 0.5, 1].map((ratio) => {
      const x = 10 + ratio * 250;
      const label = ratio === 0 ? `-${scopeLabels[activeScope] || activeScope}` : ratio === 1 ? "now" : "mid";
      return `<line x1="${x}" x2="${x}" y1="16" y2="104" stroke="var(--lumi-border)" stroke-width="1" stroke-dasharray="3 4"></line><text x="${x}" y="116" fill="var(--lumi-text-muted)" font-size="8" text-anchor="middle">${label}</text>`;
    }).join("");
    const labels = labelSamples.map((sample) => {
      const x = scaleX(sample, samples, scopeMs, now);
      const y = scaleY(sample.rss, max);
      return `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="3" fill="var(--lumi-primary)"></circle><text x="${x.toFixed(1)}" y="${Math.max(10, y - 7).toFixed(1)}" fill="var(--lumi-text)" font-size="8" text-anchor="middle">${bytes(sample.rss)}</text>`;
    }).join("");
    memoryChart.innerHTML = `
      ${grid}
      ${vertical}
      ${points ? `<polyline points="${points}" fill="none" stroke="var(--lumi-primary)" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"></polyline>` : ""}
      ${labels}
    `;
  };

  const drawLogs = (logs) => {
    if (!logChart) return;
    const counts = logs.levels || logs;
    const entries = levels.map(([level, label, token]) => [level, label, token, Number(counts[level] || 0)]);
    const max = Math.max(...entries.map(([, , , value]) => value), 1);
    const range = encodeURIComponent(String(logs.scope_ms || 5 * 60 * 1000));
    logChart.innerHTML = entries.map(([level, label, token, value], index) => {
      const height = Math.max(4, (value / max) * 76);
      const x = 22 + index * 68;
      const y = 92 - height;
      const href = `/admin/logs?range=${range}&level=${encodeURIComponent(level)}&limit=500`;
      return `<a href="${href}" aria-label="${escapeAttr(label)}: ${value} logs"><rect x="${x}" y="${y}" width="38" height="${height}" rx="6" fill="var(--lumi-${token})"></rect><text x="${x + 19}" y="${Math.max(14, y - 5)}" text-anchor="middle" fill="var(--lumi-text)" font-size="10">${value}</text><text x="${x + 19}" y="112" text-anchor="middle" fill="var(--lumi-text-muted)" font-size="10">${level}</text></a>`;
    }).join("");
    if (logSummary) {
      logSummary.innerHTML = entries.map(([level, label, , value]) => {
        const href = `/admin/logs?range=${range}&level=${encodeURIComponent(level)}&limit=500`;
        const badge = level === "error" ? "danger" : level === "warn" ? "warning" : level === "info" ? "info" : "muted";
        return `<a class="badge ${badge}" href="${href}">${label}: ${value}</a>`;
      }).join("");
    }
  };

  const syncScopeButtons = () => {
    scopeButtons.forEach((button) => {
      const active = button.dataset.dashboardScope === activeScope;
      button.classList.toggle("active", active);
      button.setAttribute("aria-pressed", active ? "true" : "false");
    });
    if (memoryScopeLabel) memoryScopeLabel.textContent = scopeLabels[activeScope] || activeScope;
    if (logScopeLabel) logScopeLabel.textContent = scopeLabels[activeScope] || activeScope;
  };

  const refresh = async () => {
    try {
      syncScopeButtons();
      const response = await fetch(`/api/admin/dashboard-metrics?scope=${encodeURIComponent(activeScope)}`, { cache: "no-store" });
      const data = await response.json();
      if (!response.ok) throw new Error(data.error || "Metrics unavailable.");
      setMetric("uptime", duration(data.uptime_seconds));
      setMetric("rss", bytes(data.memory.rss));
      setMetric("heap", `${bytes(data.memory.heap_used)} / ${bytes(data.memory.heap_total)}`);
      setMetric("plugins", `${data.plugins.enabled} / ${data.plugins.total}`);
      setMetric("users", data.counts.users);
      setMetric("commands", data.counts.commands);
      if (status) {
        status.textContent = "Live";
        status.className = "status-indicator status-success";
      }
      drawMemory(data);
      drawLogs(data.logs);
    } catch (error) {
      if (status) {
        status.textContent = error.message;
        status.className = "status-indicator status-danger";
      }
    }
  };

  scopeButtons.forEach((button) => {
    button.addEventListener("click", () => {
      activeScope = button.dataset.dashboardScope || "5m";
      window.localStorage.setItem("lumi-dashboard-scope", activeScope);
      refresh();
    });
  });

  refresh();
  window.setInterval(refresh, 10000);
})();
