import { QueryClient } from "@tanstack/react-query";
export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL_BACKEND ?? "";
async function throwIfResNotOk(res) {
    if (!res.ok) {
        if (res.status === 401) {
            localStorage.removeItem("token");
            if (!window.location.pathname.startsWith("/auth")) {
                window.location.href = "/auth";
                throw new Error(`${res.status}: Unauthorized`);
            }
            return;
        }
        // Try to parse the response as JSON for a more meaningful error message
        let message = `${res.status}: ${res.statusText}`;
        try {
            const errorBody = await res.clone().json();
            if (errorBody?.error) {
                message = errorBody.error;
            }
            else if (errorBody?.message) {
                message = errorBody.message;
            }
            else if (errorBody?.detail) {
                message = errorBody.detail;
            }
        }
        catch {
            // fallback to reading raw text so no error is lost
            try {
                const text = await res.clone().text();
                if (text?.trim()) {
                    message = text.trim();
                }
            }
            catch { }
        }
        throw new Error(message);
    }
}
export async function apiRequest(method, url, data) {
    const token = localStorage.getItem("token");
    const isFormData = typeof FormData !== "undefined" && data instanceof FormData;
    const isFileLike = (typeof File !== "undefined" && data instanceof File) ||
        (typeof Blob !== "undefined" && data instanceof Blob);
    const isArrayBufferLike = (typeof ArrayBuffer !== "undefined" && data instanceof ArrayBuffer) ||
        (typeof Uint8Array !== "undefined" && data instanceof Uint8Array) ||
        (data != null && data?.constructor?.name === "Buffer"); // Node Buffer
    // Decide Content-Type header appropriately:
    const headers = {
        ...(token ? { Authorization: `Bearer ${token}` } : {}),
    };
    if (!isFormData) {
        if (isFileLike) {
            // File/Blob: use its own MIME type if present, otherwise fallback
            const mime = data.type || "application/octet-stream";
            headers["Content-Type"] = mime;
        }
        else if (isArrayBufferLike) {
            // ArrayBuffer / Buffer / Uint8Array: use generic octet-stream
            headers["Content-Type"] = "application/octet-stream";
        }
        else {
            // Normal JSON body
            headers["Content-Type"] = "application/json";
        }
    }
    // If FormData, we must NOT set Content-Type (browser will set multipart boundary)
    // Build final body
    const finalBody = isFormData
        ? data
        : isFileLike
            ? // File/Blob can be passed directly as BodyInit
                data
            : isArrayBufferLike
                ? // ArrayBuffer / Uint8Array / Buffer -> convert to Uint8Array if needed
                    data
                : data !== undefined
                    ? JSON.stringify(data)
                    : undefined;
    const res = await fetch(`${API_BASE_URL}${url}`, {
        method,
        headers,
        body: finalBody,
        credentials: "include",
    });
    await throwIfResNotOk(res);
    return res;
}
export const getQueryFn = ({ on401: unauthorizedBehavior }) => async ({ queryKey }) => {
    const url = `${API_BASE_URL}${queryKey[0]}`;
    const token = localStorage.getItem("token");
    const res = await fetch(url, {
        headers: {
            ...(token ? { Authorization: `Bearer ${token}` } : {}),
        },
        credentials: "include",
    });
    if (unauthorizedBehavior === "returnNull" &&
        (res.status === 401 || res.status === 403)) {
        return null;
    }
    await throwIfResNotOk(res);
    return await res.json();
};
export const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            queryFn: getQueryFn({ on401: "throw" }),
            refetchInterval: false,
            refetchOnWindowFocus: false,
            refetchOnMount: true,
            staleTime: 0,
            retry: false,
        },
        mutations: {
            retry: false,
        },
    },
});
