const ERROR_REPORT_ENDPOINT = "/api/client-errors";

interface ErrorReport {
  message: string;
  stack?: string;
  source: "boundary" | "unhandled" | "rejection" | "manual";
  url: string;
  timestamp: number;
  userAgent: string;
  sessionId?: string;
}

const reportQueue: ErrorReport[] = [];
let flushTimer: ReturnType<typeof setTimeout> | null = null;

function getSessionId(): string | undefined {
  try {
    const raw = localStorage.getItem("omniai:session") || sessionStorage.getItem("omniai:session");
    if (!raw) return undefined;
    const parsed = JSON.parse(raw);
    return parsed?.user?.sessionId ?? undefined;
  } catch {
    return undefined;
  }
}

function flush() {
  if (reportQueue.length === 0) return;
  const batch = reportQueue.splice(0, 10);
  const payload = new Blob([JSON.stringify({ errors: batch })], { type: "application/json" });
  if (navigator.sendBeacon?.(ERROR_REPORT_ENDPOINT, payload)) return;

  void fetch(ERROR_REPORT_ENDPOINT, {
    method: "POST",
    body: JSON.stringify({ errors: batch }),
    headers: { "Content-Type": "application/json" },
    credentials: "include",
    keepalive: true,
  }).catch(() => {});
}

function scheduleFlush() {
  if (flushTimer) return;
  flushTimer = setTimeout(() => {
    flushTimer = null;
    flush();
  }, 2000);
}

export function reportError(error: unknown, source: ErrorReport["source"] = "manual") {
  const err = error instanceof Error ? error : new Error(String(error));
  const report: ErrorReport = {
    message: err.message,
    stack: err.stack?.slice(0, 2000),
    source,
    url: window.location.href,
    timestamp: Date.now(),
    userAgent: navigator.userAgent,
    sessionId: getSessionId(),
  };
  reportQueue.push(report);
  scheduleFlush();
}
