import { createClient, type SupabaseClient } from '@supabase/supabase-js';
import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
import type { Database } from '@colectivo/types';

let supabase: SupabaseClient<Database> | null = null;

/**
 * GoTrue's default lock uses `navigator.locks.request()`. In Playwright's
 * headless Chromium, a lock acquired in one page context can fail to release
 * after navigation, so every subsequent `supabase.from(...).select()` hangs on
 * `getAccessToken() -> getSession()` which awaits `initializePromise` which
 * awaits the never-resolved lock. A pass-through lock is safe here because
 * we're a single-tab PWA (no cross-tab coordination needed) and BroadcastChannel
 * handles multi-tab sync independently.
 */
const passThroughLock = async <R>(
	_name: string,
	_acquireTimeout: number,
	fn: () => Promise<R>
): Promise<R> => fn();

export function getSupabase(): SupabaseClient<Database> {
	if (!supabase) {
		supabase = createClient<Database>(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
			auth: {
				autoRefreshToken: true,
				persistSession: true,
				// detectSessionInUrl is disabled: the /auth/callback page explicitly calls
				// exchangeCodeForSession so there is only one code-exchange attempt.
				detectSessionInUrl: false,
				// PKCE flow — required for SPA/PWA OAuth
				flowType: 'pkce',
				lock: passThroughLock
			}
		});
	}
	return supabase;
}
