import { createClient as createSupabaseClient, type SupabaseClient } from '@supabase/supabase-js';

import type { Database, SupabaseConfig } from './types.js';

// Typed client alias used throughout the app.
export type AppSupabaseClient = SupabaseClient<Database>;

// Inline serial lock — replaces Supabase's default `navigator.locks` based
// lock that occasionally throws "Lock was stolen by another request" when
// the same origin opens multiple tabs / Tauri windows / HMR-reloaded
// modules. We only have one client instance per process so a simple promise
// chain serialises token-refresh fine without cross-tab coordination.
const acquireLock = (() => {
  let chain: Promise<unknown> = Promise.resolve();
  return async <R>(_name: string, _acquireTimeout: number, fn: () => Promise<R>): Promise<R> => {
    const next = chain.then(() => fn(), () => fn());
    chain = next.catch(() => undefined);
    return next;
  };
})();

export function createClient(config: SupabaseConfig): AppSupabaseClient {
  return createSupabaseClient<Database>(config.url, config.anonKey, {
    auth: {
      storage: config.sessionStorage,
      autoRefreshToken: true,
      persistSession: true,
      detectSessionInUrl: config.detectSessionInUrl ?? false,
      lock: acquireLock,
    },
  });
}
