import { describe, it, expect, beforeEach } from 'vitest';
import {
	registerEdgePathCalculator,
	unregisterEdgePathCalculator,
	resolveEdgePathCalculator,
	hasCustomEdgePathCalculator,
	getCustomEdgePathCalculatorNames,
	clearCustomEdgePathCalculators,
} from '../utils/edge-path-registry';

// =============================================================================
// Setup
// =============================================================================

beforeEach(() => {
	clearCustomEdgePathCalculators();
});

const dummyCalc = () => ({ path: 'M0 0 L100 100', labelX: 50, labelY: 50 });

// =============================================================================
// Tests
// =============================================================================

describe('edge-path-registry', () => {
	it('registers and retrieves a custom calculator', () => {
		registerEdgePathCalculator('custom', dummyCalc);
		expect(hasCustomEdgePathCalculator('custom')).toBe(true);
		expect(resolveEdgePathCalculator('custom')).toBe(dummyCalc);
	});

	it('unregisters a custom calculator', () => {
		registerEdgePathCalculator('custom', dummyCalc);
		expect(unregisterEdgePathCalculator('custom')).toBe(true);
		expect(hasCustomEdgePathCalculator('custom')).toBe(false);
	});

	it('returns false when unregistering unknown calculator', () => {
		expect(unregisterEdgePathCalculator('nonexistent')).toBe(false);
	});

	it('lists registered calculator names', () => {
		registerEdgePathCalculator('a', dummyCalc);
		registerEdgePathCalculator('b', dummyCalc);
		expect(getCustomEdgePathCalculatorNames().sort()).toEqual(['a', 'b']);
	});

	it('clears all custom calculators', () => {
		registerEdgePathCalculator('a', dummyCalc);
		registerEdgePathCalculator('b', dummyCalc);
		clearCustomEdgePathCalculators();
		expect(getCustomEdgePathCalculatorNames()).toHaveLength(0);
	});

	it('falls back to built-in calculators', () => {
		// 'bezierHorizontal' is a built-in type
		const calc = resolveEdgePathCalculator('bezierHorizontal');
		expect(calc).toBeDefined();
		expect(typeof calc).toBe('function');
	});

	it('custom calculator takes precedence over built-in', () => {
		registerEdgePathCalculator('bezierHorizontal', dummyCalc);
		expect(resolveEdgePathCalculator('bezierHorizontal')).toBe(dummyCalc);
	});

	it('falls back to default built-in for unknown calculators', () => {
		// Built-in getEdgePathCalculator returns bezierHorizontal as default
		const calc = resolveEdgePathCalculator('nonexistent');
		expect(calc).toBeDefined();
		expect(typeof calc).toBe('function');
	});
});
