// KCC — Telemetry (self-improvement signals)
// Auto-captures errors, dead-button clicks, page changes.
// Buffered locally, flushed every 30s to /api/self-improve/telemetry.

(function () {
  const BUFFER_KEY = "kcc:telemetry-buf";
  const FLUSH_INTERVAL = 30000;
  const MAX_BUFFER = 100;

  function readBuf() {
    try { return JSON.parse(localStorage.getItem(BUFFER_KEY) || "[]"); } catch { return []; }
  }
  function writeBuf(arr) {
    try { localStorage.setItem(BUFFER_KEY, JSON.stringify(arr.slice(-MAX_BUFFER))); } catch {}
  }
  function currentPage() {
    return (typeof window !== "undefined" && window.__kcc_currentPage) || "unknown";
  }

  function push(type, detail) {
    const buf = readBuf();
    buf.push({
      type,
      page: currentPage(),
      detail: typeof detail === "string" ? detail.slice(0, 280) : (detail ? JSON.stringify(detail).slice(0, 280) : null),
      ts: Date.now(),
    });
    writeBuf(buf);
  }

  async function flush() {
    const buf = readBuf();
    if (!buf.length) return;
    const batch = buf.slice();
    writeBuf([]); // optimistic clear
    try {
      // Send one POST per item (KV append model). Keep it small — 1-2 calls per flush typically.
      for (const item of batch) {
        await fetch("/api/self-improve/telemetry", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(item),
        }).catch(() => null);
      }
    } catch {
      // restore on failure
      writeBuf([...batch, ...readBuf()]);
    }
  }

  // === Auto-capture: window errors ===
  window.addEventListener("error", (e) => {
    push("error", `${e.message} @ ${e.filename}:${e.lineno}`);
  });
  window.addEventListener("unhandledrejection", (e) => {
    push("error", `unhandled: ${String(e.reason).slice(0, 200)}`);
  });

  // === Auto-capture: dead-button clicks ===
  // A click is "dead" if a <button> was clicked but no toast appeared and no nav happened within 800ms.
  let lastNav = currentPage();
  let lastToastTs = 0;
  // Hook navigation: app sets window.__kcc_currentPage on each route change.
  setInterval(() => {
    const p = currentPage();
    if (p !== lastNav) { lastNav = p; lastToastTs = Date.now(); }
  }, 200);
  // Detect toast presence (DOM-based, .toast or [data-toast] elements).
  const toastObserver = new MutationObserver(() => { lastToastTs = Date.now(); });
  toastObserver.observe(document.body, { childList: true, subtree: true, attributeFilter: ["data-toast"] });

  document.addEventListener("click", (e) => {
    const btn = e.target.closest("button");
    if (!btn) return;
    const label = (btn.innerText || btn.textContent || btn.getAttribute("aria-label") || "btn").trim().slice(0, 60);
    const pageBefore = currentPage();
    setTimeout(() => {
      const pageAfter = currentPage();
      const recentToast = Date.now() - lastToastTs < 1000;
      if (!recentToast && pageBefore === pageAfter) {
        push("dead_button", `${pageBefore}: "${label}"`);
      }
    }, 900);
  }, true);

  // === Page change tracking ===
  let prevPage = currentPage();
  setInterval(() => {
    const p = currentPage();
    if (p !== prevPage) {
      push("page_change", `${prevPage} → ${p}`);
      prevPage = p;
    }
  }, 500);

  // === Periodic flush ===
  setInterval(flush, FLUSH_INTERVAL);
  // Flush on tab hide
  document.addEventListener("visibilitychange", () => { if (document.hidden) flush(); });

  // Expose manual API
  window.kccTelemetry = { push, flush, readBuf };
})();
