import { describe, it, expect, beforeEach } from 'vitest';
import {
	registerAction,
	getAction,
	hasAction,
	getAllActions,
	getActionsByCategory,
	unregisterAction,
	clearActions,
} from '../core/action-registry';
import type { ActionDefinition } from '../core/settings-types';
import { ActionCategory } from '../core/settings-types';

// Built-in actions are registered at module import time.
// Save their count to verify custom action management.

describe('action-registry', () => {
	const builtInCount = getAllActions().length;

	beforeEach(() => {
		// Remove only custom actions, keeping built-ins
		const customs = getAllActions().filter((a) => a.id.startsWith('test-'));
		for (const c of customs) {
			unregisterAction(c.id);
		}
	});

	describe('built-in actions', () => {
		it('has built-in actions registered on import', () => {
			expect(builtInCount).toBeGreaterThan(0);
		});

		it('includes well-known built-in actions', () => {
			expect(hasAction('clear-selection')).toBe(true);
			expect(hasAction('undo')).toBe(true);
			expect(hasAction('fit-to-view')).toBe(true);
		});
	});

	describe('registerAction / getAction', () => {
		it('registers and retrieves a custom action', () => {
			const action: ActionDefinition = {
				id: 'test-custom',
				label: 'Test Custom',
				description: 'A test action',
				category: ActionCategory.Custom,
				handler: () => {},
			};
			registerAction(action);
			expect(getAction('test-custom')).toEqual(action);
		});

		it('overwrites existing action with same id', () => {
			registerAction({ id: 'test-ow', label: 'V1', description: 'V1', category: ActionCategory.Custom, handler: () => {} });
			registerAction({ id: 'test-ow', label: 'V2', description: 'V2', category: ActionCategory.Custom, handler: () => {} });
			expect(getAction('test-ow')!.label).toBe('V2');
		});
	});

	describe('hasAction', () => {
		it('returns false for unknown id', () => {
			expect(hasAction('nonexistent-xyz')).toBe(false);
		});
	});

	describe('unregisterAction', () => {
		it('removes a registered action', () => {
			registerAction({ id: 'test-remove', label: 'R', description: 'R', category: ActionCategory.Custom, handler: () => {} });
			expect(unregisterAction('test-remove')).toBe(true);
			expect(hasAction('test-remove')).toBe(false);
		});

		it('returns false for unknown id', () => {
			expect(unregisterAction('nonexistent-xyz')).toBe(false);
		});
	});

	describe('getActionsByCategory', () => {
		it('returns actions filtered by category', () => {
			const viewport = getActionsByCategory(ActionCategory.Viewport);
			expect(viewport.length).toBeGreaterThan(0);
			for (const a of viewport) {
				expect(a.category).toBe(ActionCategory.Viewport);
			}
		});
	});

	describe('clearActions', () => {
		it('removes all actions', () => {
			clearActions();
			expect(getAllActions().length).toBe(0);
		});
	});
});
