/**
 * Node query functions
 */

import type { SupabaseClient } from '@supabase/supabase-js';
import type { DBGraphNode } from '../../core/types';
import { createDebug } from '../../utils/debug';

const debug = createDebug('db:nodes');

/**
 * Fetch all nodes for a graph
 */
export async function fetchGraphNodes(supabase: SupabaseClient, graphId: string): Promise<DBGraphNode[]> {
	if (!graphId) {
		throw new Error('graphId is required to fetch nodes');
	}

	const { data, error } = await supabase
		.from('nodes')
		.select('*')
		.eq('graph_id', graphId)
		.order('created_at', { ascending: true });

	if (error) {
		debug.error('Error fetching nodes for graph %s: %O', graphId, error);
		throw error;
	}

	return (data as DBGraphNode[]) || [];
}

/**
 * Fetch a single node by ID
 */
export async function fetchGraphNode(supabase: SupabaseClient, nodeId: string): Promise<DBGraphNode | null> {
	if (!nodeId) {
		throw new Error('nodeId is required to fetch node');
	}

	const { data, error } = await supabase.from('nodes').select('*').eq('id', nodeId).single();

	if (error) {
		if (error.code === 'PGRST116') {
			return null; // Not found
		}
		debug.error('Error fetching node %s: %O', nodeId, error);
		throw error;
	}

	return data as DBGraphNode;
}

/**
 * Create a new node
 */
export async function createGraphNode(
	supabase: SupabaseClient,
	node: Omit<DBGraphNode, 'id' | 'created_at' | 'updated_at'>,
): Promise<DBGraphNode> {
	const { data, error } = await supabase.from('nodes').insert(node).select().single();

	if (error) {
		debug.error('Error creating node: %O', error);
		throw error;
	}

	return data as DBGraphNode;
}

/**
 * Update a node
 */
export async function updateGraphNode(
	supabase: SupabaseClient,
	nodeId: string,
	updates: Partial<Pick<DBGraphNode, 'label' | 'node_type' | 'configuration' | 'ui_properties'>>,
): Promise<DBGraphNode> {
	const { data, error } = await supabase
		.from('nodes')
		.update({ ...updates, updated_at: new Date().toISOString() })
		.eq('id', nodeId)
		.select()
		.single();

	if (error) {
		debug.error('Error updating node %s: %O', nodeId, error);
		throw error;
	}

	return data as DBGraphNode;
}

/**
 * Delete a node
 */
export async function deleteGraphNode(supabase: SupabaseClient, nodeId: string): Promise<void> {
	const { error } = await supabase.from('nodes').delete().eq('id', nodeId);

	if (error) {
		debug.error('Error deleting node %s: %O', nodeId, error);
		throw error;
	}
}
