/**
 * Canvas DB Provider
 *
 * Provides a storage adapter to the canvas components.
 */

import React, { createContext, useContext, useEffect, useRef } from 'react';
import { useSetAtom, useAtomValue } from 'jotai';
import type { CanvasStorageAdapter } from './adapter';
import { storageAdapterAtom } from './adapter';

export interface CanvasDbProviderProps {
	/** Storage adapter */
	adapter: CanvasStorageAdapter;
	children: React.ReactNode;
}

const AdapterContext = createContext<CanvasStorageAdapter | null>(null);

/**
 * Provider that makes a storage adapter available to canvas hooks and components.
 *
 * @example
 * ```tsx
 * <CanvasDbProvider adapter={new InMemoryStorageAdapter()}>
 *   <Canvas ... />
 * </CanvasDbProvider>
 * ```
 */
export function CanvasDbProvider({ adapter, children }: CanvasDbProviderProps) {
	const setAdapter = useSetAtom(storageAdapterAtom);

	const prevAdapterRef = useRef<CanvasStorageAdapter | null>(null);
	const resolved = adapter === prevAdapterRef.current ? prevAdapterRef.current : adapter;
	prevAdapterRef.current = resolved;

	useEffect(() => {
		setAdapter(resolved);
		return () => setAdapter(null);
	}, [resolved, setAdapter]);

	return <AdapterContext value={resolved}>{children}</AdapterContext>;
}

/**
 * Hook to access the current storage adapter
 */
export function useStorageAdapter(): CanvasStorageAdapter {
	const contextAdapter = useContext(AdapterContext);
	const atomAdapter = useAtomValue(storageAdapterAtom);
	const adapter = contextAdapter || atomAdapter;

	if (!adapter) {
		throw new Error('useStorageAdapter must be used within CanvasDbProvider');
	}

	return adapter;
}

// =============================================================================
// Internal Supabase helpers (used by db/hooks/* — NOT exported from db/index.ts)
// =============================================================================

/**
 * Raw Supabase client atom — used internally by Supabase-specific query hooks.
 * Not part of the public API. Use `useStorageAdapter()` for public consumption.
 */
import { atom, useAtomValue as useAtomVal } from 'jotai';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const supabaseClientAtom = atom<any>(null);

/**
 * Internal hook for db hooks that need the raw Supabase client.
 * Not part of the public API.
 */
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function useSupabaseClient(): any {
	const client = useAtomVal(supabaseClientAtom);
	if (!client) {
		throw new Error('useSupabaseClient: no Supabase client available. Use CanvasDbProvider with a SupabaseStorageAdapter.');
	}
	return client;
}

