// ABOUTME: Hey-API client configuration for Tauri environment.
// ABOUTME: Integrates with Tauri HTTP plugin and handles token refresh.

import { apiBase } from "@/lib/config";
import { getToken } from "@/lib/tauri-bridge";
import { getTauriFetch, shouldSkipRefresh } from "@/lib/tauri-fetch";
import type { ClientOptions, Config } from "./generated/seren-core/client";

/**
 * Custom fetch that uses Tauri HTTP plugin when available.
 */
const customFetch: typeof globalThis.fetch = async (input, init) => {
  const fetchFn = await getTauriFetch();

  // Always create a Request so we can safely retry by cloning it
  const request = new Request(input, init);
  const retryRequest = request.clone();

  const response = await fetchFn(request);

  // Handle 401 with auto-refresh and retry once (skip auth endpoints to avoid loops)
  if (response.status === 401 && !shouldSkipRefresh(request)) {
    // Dynamic import to avoid circular dependency
    const { refreshAccessToken } = await import("@/services/auth");
    const refreshed = await refreshAccessToken();

    if (refreshed) {
      const token = await getToken();
      if (token) {
        retryRequest.headers.set("Authorization", `Bearer ${token}`);

        // Close original response body before retrying (best-effort)
        try {
          await response.body?.cancel();
        } catch {
          // noop
        }

        return fetchFn(retryRequest);
      }
    }
  }

  if (
    response.status >= 400 &&
    request.url.includes("api.serendb.com") &&
    !request.url.includes("/support/report")
  ) {
    void import("@/lib/support/hook")
      .then(({ captureHttpFailure }) => captureHttpFailure(request, response))
      .catch(() => {});
  }

  return response;
};

/**
 * Create the client configuration for hey-api.
 * This is called by the generated client during initialization.
 */
export const createClientConfig = <T extends ClientOptions>(
  override?: Config<T>,
): Config<T> => {
  const resolvedBaseUrl =
    typeof override?.baseUrl === "string" && override.baseUrl.length > 0
      ? new URL(override.baseUrl, apiBase).toString()
      : apiBase;

  return {
    ...override,
    // Sub-spec clients pass relative baseUrls (e.g. '/publishers/seren-db').
    // Resolve them against the configured API root instead of dropping them.
    baseUrl: resolvedBaseUrl,
    fetch: customFetch,
  } as Config<T>;
};
