// Client-side fetch helper with automatic HttpOnly cookie refresh.

export interface ApiResponse<T = unknown> {
  data: T;
  meta: { timestamp: string; version: "v1" };
  error: null | { message: string; code?: string };
}

const USER_KEY = "ledgerone_user";

export function getStoredToken(): string {
  return "";
}

export function getStoredUser<T = unknown>(): T | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = localStorage.getItem(USER_KEY);
    return raw ? (JSON.parse(raw) as T) : null;
  } catch {
    return null;
  }
}

export function storeAuthTokens(data: {
  accessToken?: string;
  refreshToken?: string;
  user: unknown;
}): void {
  localStorage.setItem(USER_KEY, JSON.stringify(data.user));
}

export function clearAuth(): void {
  localStorage.removeItem(USER_KEY);
}

async function tryRefresh(): Promise<boolean> {
  try {
    const res = await fetch("/api/auth/refresh", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
    });
    if (!res.ok) {
      clearAuth();
      return false;
    }
    const payload = (await res.json()) as ApiResponse<unknown>;
    if (payload.error) {
      clearAuth();
      return false;
    }
    return true;
  } catch {
    clearAuth();
    return false;
  }
}

export async function apiFetch<T = unknown>(
  path: string,
  options: RequestInit = {}
): Promise<ApiResponse<T>> {
  const headers: Record<string, string> = {
    ...(options.headers as Record<string, string>),
  };
  if (
    options.body &&
    typeof options.body === "string" &&
    !headers["Content-Type"]
  ) {
    headers["Content-Type"] = "application/json";
  }

  let res = await fetch(path, { ...options, headers });

  // Auto-refresh on 401
  if (res.status === 401) {
    const refreshed = await tryRefresh();
    if (refreshed) {
      res = await fetch(path, { ...options, headers });
    } else {
      if (typeof window !== "undefined") {
        window.location.href = "/login";
      }
      return {
        data: null as T,
        meta: { timestamp: new Date().toISOString(), version: "v1" },
        error: { message: "Session expired. Please sign in again." },
      };
    }
  }

  return res.json() as Promise<ApiResponse<T>>;
}
