import { describe, it, expect } from 'vitest';
import {
	DEFAULT_GESTURE_RULES,
	mergeRules,
	formatRuleLabel,
} from '../core/gesture-rules-defaults';
import type { GestureRule, GesturePattern } from '../core/gesture-rules-types';

describe('gesture-rules-defaults', () => {
	describe('DEFAULT_GESTURE_RULES', () => {
		it('is a non-empty array', () => {
			expect(Array.isArray(DEFAULT_GESTURE_RULES)).toBe(true);
			expect(DEFAULT_GESTURE_RULES.length).toBeGreaterThan(0);
		});

		it('every rule has required fields', () => {
			for (const rule of DEFAULT_GESTURE_RULES) {
				expect(rule).toHaveProperty('id');
				expect(rule).toHaveProperty('pattern');
				expect(rule).toHaveProperty('actionId');
			}
		});

		it('has unique IDs', () => {
			const ids = DEFAULT_GESTURE_RULES.map((r) => r.id);
			expect(new Set(ids).size).toBe(ids.length);
		});
	});

	describe('mergeRules', () => {
		const baseRules: GestureRule[] = [
			{ id: 'r1', pattern: { gesture: 'tap', target: 'node' }, actionId: 'select', priority: 0, source: 'default' } as any,
			{ id: 'r2', pattern: { gesture: 'drag', target: 'background' }, actionId: 'pan', priority: 0, source: 'default' } as any,
		];

		it('consumer rules override defaults by ID', () => {
			const consumer: GestureRule[] = [
				{ id: 'r1', pattern: { gesture: 'tap', target: 'node' }, actionId: 'none', priority: 10, source: 'consumer' } as any,
			];
			const merged = mergeRules(baseRules, consumer);
			const r1 = merged.find((r) => r.id === 'r1');
			expect(r1?.actionId).toBe('none');
		});

		it('consumer rules are appended when ID is new', () => {
			const consumer: GestureRule[] = [
				{ id: 'r3', pattern: { gesture: 'tap', target: 'edge' }, actionId: 'select-edge', priority: 0, source: 'consumer' } as any,
			];
			const merged = mergeRules(baseRules, consumer);
			expect(merged.length).toBe(3);
		});

		it('preserves defaults when consumer is empty', () => {
			const merged = mergeRules(baseRules, []);
			expect(merged.length).toBe(baseRules.length);
		});
	});

	describe('formatRuleLabel', () => {
		it('formats a simple pattern', () => {
			const pattern: GesturePattern = { gesture: 'tap', target: 'node', source: 'finger' };
			const label = formatRuleLabel(pattern);
			expect(typeof label).toBe('string');
			expect(label.length).toBeGreaterThan(0);
		});

		it('includes modifier info', () => {
			const pattern: GesturePattern = { gesture: 'tap', target: 'node', modifiers: { shift: true } };
			const label = formatRuleLabel(pattern);
			expect(label.toLowerCase()).toContain('shift');
		});
	});
});
