import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createStore } from 'jotai';
import type { CommandDefinition } from '../commands/types';
import {
	commandLineStateAtom,
	provideInputAtom,
	closeCommandLineAtom,
} from '../commands/store';
import { handlePickedPoint, handlePickedNode, cancelCommand } from '../commands/executor';

function freshStore() {
	return createStore();
}

function makeCommand(overrides: Partial<CommandDefinition> = {}): CommandDefinition {
	return {
		name: 'test-cmd',
		description: 'Test command',
		category: 'nodes',
		inputs: [],
		execute: vi.fn(),
		...overrides,
	};
}

describe('commands/executor', () => {
	let store: ReturnType<typeof createStore>;

	beforeEach(() => {
		store = freshStore();
	});

	describe('handlePickedPoint', () => {
		it('sets provideInputAtom with point', () => {
			const command = makeCommand({
				inputs: [{ name: 'pos', type: 'point', prompt: 'Pick point' }],
			});
			store.set(commandLineStateAtom, {
				phase: 'collecting',
				command,
				inputIndex: 0,
				collected: {},
			});
			handlePickedPoint(store.set, { x: 100, y: 200 });
			// After provideInput, state should have advanced
			const state = store.get(commandLineStateAtom);
			// With single input, it should have collected and set to normal
			expect(state.phase).toBe('collecting');
		});
	});

	describe('handlePickedNode', () => {
		it('provides node as input', () => {
			const command = makeCommand({
				inputs: [{ name: 'target', type: 'node', prompt: 'Pick node' }],
			});
			store.set(commandLineStateAtom, {
				phase: 'collecting',
				command,
				inputIndex: 0,
				collected: {},
			});
			const mockNode = { id: 'n1' } as any;
			handlePickedNode(store.set, mockNode);
			const state = store.get(commandLineStateAtom);
			expect(state.phase).toBe('collecting');
		});
	});

	describe('cancelCommand', () => {
		it('closes command line and resets state', () => {
			store.set(commandLineStateAtom, { phase: 'executing', command: makeCommand() });
			cancelCommand(store.set);
			expect(store.get(commandLineStateAtom).phase).toBe('idle');
		});
	});
});
