/**
 * Hook for updating a node with optimistic updates
 */

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useSetAtom } from 'jotai';
import type { DBGraphNode } from '../../core/types';
import { startMutationAtom, completeMutationAtom } from '../../core/sync-store';
import { useSupabaseClient } from '../provider';
import { updateGraphNode } from '../queries/nodes';
import { canvasKeys } from './keys';

export interface UpdateNodeVariables {
	nodeId: string;
	graphId: string;
	updates: Partial<Pick<DBGraphNode, 'label' | 'node_type' | 'configuration' | 'ui_properties'>>;
}

/**
 * Hook to update a node with optimistic updates
 */
export function useUpdateNode() {
	const queryClient = useQueryClient();
	const supabase = useSupabaseClient();
	const startMutation = useSetAtom(startMutationAtom);
	const completeMutation = useSetAtom(completeMutationAtom);

	return useMutation({
		mutationFn: async ({ nodeId, updates }: UpdateNodeVariables) => {
			return updateGraphNode(supabase, nodeId, updates);
		},
		onMutate: async ({ nodeId, graphId, updates }) => {
			startMutation();

			// Cancel any outgoing refetches
			await queryClient.cancelQueries({ queryKey: canvasKeys.nodes(graphId) });

			// Snapshot the previous value
			const previousNodes = queryClient.getQueryData<DBGraphNode[]>(canvasKeys.nodes(graphId));

			// Optimistically update the cache
			if (previousNodes) {
				queryClient.setQueryData<DBGraphNode[]>(canvasKeys.nodes(graphId), (old) =>
					old?.map((node) =>
						node.id === nodeId
							? {
									...node,
									...updates,
									updated_at: new Date().toISOString(),
								}
							: node,
					),
				);
			}

			return { previousNodes, graphId };
		},
		onError: (_err, _variables, context) => {
			// Rollback on error
			if (context?.previousNodes) {
				queryClient.setQueryData(canvasKeys.nodes(context.graphId), context.previousNodes);
			}
			completeMutation(false);
		},
		onSuccess: () => {
			completeMutation(true);
		},
		onSettled: (_data, _error, variables) => {
			// Invalidate to ensure fresh data
			queryClient.invalidateQueries({ queryKey: canvasKeys.nodes(variables.graphId) });
		},
	});
}
