/**
 * Hook for creating a new edge
 */

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

export type CreateEdgeVariables = Omit<DBGraphEdge, 'id' | 'created_at' | 'updated_at'>;

/**
 * Hook to create a new edge
 */
export function useCreateEdge() {
	const queryClient = useQueryClient();
	const supabase = useSupabaseClient();
	const startMutation = useSetAtom(startMutationAtom);
	const completeMutation = useSetAtom(completeMutationAtom);

	return useMutation({
		mutationFn: async (edge: CreateEdgeVariables) => {
			return createGraphEdge(supabase, edge);
		},
		onMutate: async (edge) => {
			startMutation();

			// Cancel any outgoing refetches
			await queryClient.cancelQueries({ queryKey: canvasKeys.edges(edge.graph_id) });

			// Snapshot the previous value
			const previousEdges = queryClient.getQueryData<DBGraphEdge[]>(canvasKeys.edges(edge.graph_id));

			// Optimistically add the new edge with a temporary ID
			const optimisticEdge: DBGraphEdge = {
				...edge,
				id: `temp-${Date.now()}`,
				created_at: new Date().toISOString(),
				updated_at: new Date().toISOString(),
			};

			queryClient.setQueryData<DBGraphEdge[]>(canvasKeys.edges(edge.graph_id), (old) => [...(old || []), optimisticEdge]);

			return { previousEdges, graphId: edge.graph_id, optimisticId: optimisticEdge.id };
		},
		onError: (_err, _variables, context) => {
			// Rollback on error
			if (context?.previousEdges) {
				queryClient.setQueryData(canvasKeys.edges(context.graphId), context.previousEdges);
			}
			completeMutation(false);
		},
		onSuccess: (newEdge, _variables, context) => {
			// Replace optimistic edge with real edge
			if (context) {
				queryClient.setQueryData<DBGraphEdge[]>(canvasKeys.edges(context.graphId), (old) =>
					old?.map((edge) => (edge.id === context.optimisticId ? newEdge : edge)),
				);
			}
			completeMutation(true);
		},
		onSettled: (_data, _error, variables) => {
			// Invalidate to ensure fresh data
			queryClient.invalidateQueries({ queryKey: canvasKeys.edges(variables.graph_id) });
		},
	});
}
