import { describe, it, expect } from 'vitest';
import { DEFAULT_CONTEXT, PICK_NODE_CONTEXT, PICK_NODES_CONTEXT, PICK_POINT_CONTEXT, INPUT_MODE_CONTEXTS } from '../gestures/pointer-contexts';
import { POINTER_BINDINGS } from '../gestures/pointer-bindings';
import { KEYBOARD_BINDINGS } from '../gestures/keyboard-bindings';

describe('pointer-contexts', () => {
	it('DEFAULT_CONTEXT has id "default"', () => {
		expect(DEFAULT_CONTEXT.id).toBe('default');
	});

	it('DEFAULT_CONTEXT priority is 100', () => {
		expect(DEFAULT_CONTEXT.priority).toBe(100);
	});

	it('DEFAULT_CONTEXT has >20 bindings', () => {
		expect(DEFAULT_CONTEXT.bindings.length).toBeGreaterThan(20);
	});

	it('POINTER_BINDINGS has tap-node binding', () => {
		const tapNode = POINTER_BINDINGS.find((b) => b.id === 'tap-node');
		expect(tapNode).toBeDefined();
		expect(tapNode!.actionId).toBe('select-node');
	});

	it('POINTER_BINDINGS covers all gesture types', () => {
		const types = new Set(POINTER_BINDINGS.map((b) => (b.pattern as any).type).filter(Boolean));
		expect(types.has('tap')).toBe(true);
		expect(types.has('drag')).toBe(true);
		expect(types.has('long-press')).toBe(true);
		expect(types.has('pinch')).toBe(true);
	});

	it('KEYBOARD_BINDINGS all have consumeInput: true', () => {
		for (const binding of KEYBOARD_BINDINGS) {
			expect(binding.consumeInput).toBe(true);
		}
	});

	it('KEYBOARD_BINDINGS covers undo/redo', () => {
		const undoBindings = KEYBOARD_BINDINGS.filter((b) => b.actionId === 'undo');
		const redoBindings = KEYBOARD_BINDINGS.filter((b) => b.actionId === 'redo');
		expect(undoBindings.length).toBeGreaterThan(0);
		expect(redoBindings.length).toBeGreaterThan(0);
	});

	it('no duplicate binding IDs in DEFAULT_CONTEXT', () => {
		const ids = DEFAULT_CONTEXT.bindings.map((b) => b.id);
		const unique = new Set(ids);
		expect(unique.size).toBe(ids.length);
	});

	it('PICK_NODE_CONTEXT has priority 5', () => {
		expect(PICK_NODE_CONTEXT.priority).toBe(5);
	});

	it('PICK_NODES_CONTEXT has finish-pick-nodes binding', () => {
		const finish = PICK_NODES_CONTEXT.bindings.find((b) => b.actionId === 'finish-pick-nodes');
		expect(finish).toBeDefined();
	});

	it('PICK_POINT_CONTEXT has resolve-pick-point binding', () => {
		const resolve = PICK_POINT_CONTEXT.bindings.find((b) => b.actionId === 'resolve-pick-point');
		expect(resolve).toBeDefined();
	});

	it('INPUT_MODE_CONTEXTS maps normal to null', () => {
		expect(INPUT_MODE_CONTEXTS.normal).toBeNull();
	});

	it('INPUT_MODE_CONTEXTS maps pickNode to PICK_NODE_CONTEXT', () => {
		expect(INPUT_MODE_CONTEXTS.pickNode).toBe(PICK_NODE_CONTEXT);
	});
});
