/**
 * useActionExecutor Hook
 *
 * React wrapper around buildActionHelpers for convenient hook-based usage.
 * The core logic lives in action-executor.ts (headless, no React).
 */

import { useAtomValue, useStore } from 'jotai';

// Types
import type { ActionContext, ActionHelpers, CanvasEventType, EventActionMapping } from '../core/settings-types';
import { executeAction, buildActionHelpers, type ActionExecutionResult } from '../core/action-executor';
import { eventMappingsAtom, getActionForEvent } from '../core/settings-store';

// =============================================================================
// Hook Options
// =============================================================================

export interface UseActionExecutorOptions {
	/**
	 * Callback when a node needs to be deleted.
	 * Apps must provide this since deletion logic is app-specific (database, etc).
	 */
	onDeleteNode?: (nodeId: string) => Promise<void>;

	/**
	 * Callback to open a context menu.
	 * Apps provide their own context menu implementation.
	 */
	onOpenContextMenu?: (position: { x: number; y: number }, nodeId?: string) => void;

	/**
	 * Callback to create a node at a position.
	 * Apps provide their own node creation logic.
	 */
	onCreateNode?: (position: { x: number; y: number }) => Promise<void>;

	/**
	 * Callback for force layout.
	 * Apps may want to wrap this with persistence logic.
	 */
	onApplyForceLayout?: () => Promise<void>;
}

// =============================================================================
// Hook Return Type
// =============================================================================

export interface UseActionExecutorReturn {
	executeActionById: (actionId: string, context: ActionContext) => Promise<ActionExecutionResult>;
	executeEventAction: (event: CanvasEventType, context: ActionContext) => Promise<ActionExecutionResult>;
	getActionForEvent: (event: CanvasEventType) => string;
	mappings: EventActionMapping;
	helpers: ActionHelpers;
}

// =============================================================================
// Hook Implementation
// =============================================================================

export function useActionExecutor(options: UseActionExecutorOptions = {}): UseActionExecutorReturn {
	const store = useStore();
	const mappings = useAtomValue(eventMappingsAtom);

	// Delegate to headless buildActionHelpers (DRY — single source of truth)
	const helpers = buildActionHelpers(store, {
		onDeleteNode: options.onDeleteNode,
		onOpenContextMenu: options.onOpenContextMenu,
		onCreateNode: options.onCreateNode,
		onApplyForceLayout: options.onApplyForceLayout,
	});

	const executeActionById = async (actionId: string, context: ActionContext): Promise<ActionExecutionResult> => {
		return executeAction(actionId, context, helpers);
	};

	const executeEventAction = async (event: CanvasEventType, context: ActionContext): Promise<ActionExecutionResult> => {
		const actionId = getActionForEvent(mappings, event);
		return executeAction(actionId, context, helpers);
	};

	const getActionForEventFn = (event: CanvasEventType): string => {
		return getActionForEvent(mappings, event);
	};

	return {
		executeActionById,
		executeEventAction,
		getActionForEvent: getActionForEventFn,
		mappings,
		helpers,
	};
}
