/** Read a cookie value by name. */
function readCookie(name: string): string | null {
  if (typeof document === "undefined") return null;
  const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}=([^;]*)`));
  if (!match) return null;
  try {
    return decodeURIComponent(match[1]);
  } catch {
    return match[1];
  }
}

/**
 * Laravel keeps XSRF-TOKEN cookie in sync with the session after regenerate().
 * Prefer it over the static meta tag, which becomes stale after login/logout.
 */
export function getCsrfToken(): string {
  const fromCookie = readCookie("XSRF-TOKEN");
  if (fromCookie) return fromCookie;

  if (typeof document === "undefined") return "";
  return document.querySelector('meta[name="csrf-token"]')?.getAttribute("content") ?? "";
}

/** Keep the meta tag aligned with the current session CSRF token. */
export function syncCsrfMetaTag(token?: string): void {
  if (typeof document === "undefined") return;
  const value = token ?? getCsrfToken();
  if (!value) return;
  const meta = document.querySelector('meta[name="csrf-token"]');
  meta?.setAttribute("content", value);
}

/** Apply Laravel CSRF headers for mutating requests. */
export function applyCsrfHeaders(headers: Headers): void {
  const xsrf = readCookie("XSRF-TOKEN");
  if (xsrf) {
    headers.set("X-XSRF-TOKEN", xsrf);
    return;
  }

  const metaToken =
    typeof document !== "undefined"
      ? document.querySelector('meta[name="csrf-token"]')?.getAttribute("content")
      : null;
  if (metaToken) {
    headers.set("X-CSRF-TOKEN", metaToken);
  }
}
