/**
 * Command Executor
 *
 * Helper functions for executing commands and handling input collection.
 */

import type { Getter, Setter } from 'jotai';
import type { CommandDefinition, InputDefinition, Point, UINodeState } from './types';
import { commandLineStateAtom, provideInputAtom, closeCommandLineAtom } from './store';

/**
 * Collects a single input from the user.
 * Currently rejects immediately — interactive input collection
 * is not yet implemented. Pre-fill all inputs via `initialInputs`.
 */
export function collectInput(
	_get: Getter,
	_set: Setter,
	_inputDef: InputDefinition,
	_collected: Record<string, unknown>,
): Promise<unknown> {
	return Promise.reject(
		new Error('Interactive input collection is not yet implemented. Pre-fill all inputs via initialInputs.'),
	);
}

/**
 * Execute a command with interactive input collection.
 * This is the main entry point for running commands from the UI.
 */
export async function executeCommandInteractive(
	get: Getter,
	set: Setter,
	command: CommandDefinition,
	initialInputs?: Record<string, unknown>,
): Promise<void> {
	const collected: Record<string, unknown> = { ...initialInputs };

	// Collect each required input
	for (let i = 0; i < command.inputs.length; i++) {
		const inputDef = command.inputs[i];

		// Skip if already provided
		if (collected[inputDef.name] !== undefined) {
			continue;
		}

		// Use default if optional and no input needed
		if (inputDef.required === false && inputDef.default !== undefined) {
			collected[inputDef.name] = inputDef.default;
			continue;
		}

		// Update state to collecting this input
		set(commandLineStateAtom, {
			phase: 'collecting',
			command,
			inputIndex: i,
			collected,
		});

		// Wait for user to provide input
		const value = await collectInput(get, set, inputDef, collected);
		collected[inputDef.name] = value;
	}

	// All inputs collected, execute
	set(commandLineStateAtom, { phase: 'executing', command });

	// The actual execution will be handled by the context provider
	// which has access to the mutations
}

/**
 * Handle a picked point from the canvas.
 * Called by Viewport when user clicks while in pickPoint mode.
 */
export function handlePickedPoint(set: Setter, point: Point): void {
	set(provideInputAtom, point);
}

/**
 * Handle a picked node from the canvas.
 * Called by Node component when user clicks while in pickNode mode.
 */
export function handlePickedNode(set: Setter, node: UINodeState): void {
	set(provideInputAtom, node);
}

/**
 * Cancel the current command.
 */
export function cancelCommand(set: Setter): void {
	set(closeCommandLineAtom);
}
