import { describe, it, expect } from 'vitest';
import {
	createTenantId,
	createUserId,
	createNoteId,
	createClasseId,
	createEleveId
} from '$lib/types/shared';

/**
 * Unit tests for branded type helper functions.
 *
 * Branded types provide compile-time type safety (e.g. preventing
 * accidental use of a UserId where a TenantId is expected).
 * At runtime, the create functions are identity functions that
 * simply return the input string.
 */

describe('shared branded types', () => {
	// ==========================================================================
	// createTenantId
	// ==========================================================================
	describe('createTenantId', () => {
		it('should return a string', () => {
			const result = createTenantId('tenant-abc-123');
			expect(typeof result).toBe('string');
		});

		it('should preserve the input value', () => {
			const input = 'b2c3d4e5-f6a7-8901-bcde-f23456789012';
			const result = createTenantId(input);
			expect(result).toBe(input);
		});

		it('should handle empty string', () => {
			const result = createTenantId('');
			expect(result).toBe('');
		});
	});

	// ==========================================================================
	// createUserId
	// ==========================================================================
	describe('createUserId', () => {
		it('should return a string', () => {
			const result = createUserId('user-xyz-456');
			expect(typeof result).toBe('string');
		});

		it('should preserve the input value', () => {
			const input = 'a1b2c3d4-e5f6-7890-abcd-ef1234567890';
			const result = createUserId(input);
			expect(result).toBe(input);
		});
	});

	// ==========================================================================
	// createNoteId
	// ==========================================================================
	describe('createNoteId', () => {
		it('should return a string', () => {
			const result = createNoteId('note-001');
			expect(typeof result).toBe('string');
		});

		it('should preserve the input value', () => {
			const input = 'd4e5f6a7-b890-1234-cdef-567890abcdef';
			const result = createNoteId(input);
			expect(result).toBe(input);
		});
	});

	// ==========================================================================
	// createClasseId
	// ==========================================================================
	describe('createClasseId', () => {
		it('should return a string', () => {
			const result = createClasseId('classe-6eme-a');
			expect(typeof result).toBe('string');
		});

		it('should preserve the input value', () => {
			const input = 'e5f6a7b8-9012-3456-cdef-890abcdef123';
			const result = createClasseId(input);
			expect(result).toBe(input);
		});
	});

	// ==========================================================================
	// createEleveId
	// ==========================================================================
	describe('createEleveId', () => {
		it('should return a string', () => {
			const result = createEleveId('eleve-jean-dupont');
			expect(typeof result).toBe('string');
		});

		it('should preserve the input value', () => {
			const input = 'f6a7b890-1234-5678-cdef-abcdef012345';
			const result = createEleveId(input);
			expect(result).toBe(input);
		});
	});

	// ==========================================================================
	// Type safety (compile-time checks)
	// ==========================================================================
	describe('type safety', () => {
		it('should produce values that are assignable to string', () => {
			// These assignments verify that branded types are assignable to string
			const tenantId: string = createTenantId('t1');
			const userId: string = createUserId('u1');
			const noteId: string = createNoteId('n1');
			const classeId: string = createClasseId('c1');
			const eleveId: string = createEleveId('e1');

			// Use all variables to avoid unused-variable warnings
			expect(tenantId).toBe('t1');
			expect(userId).toBe('u1');
			expect(noteId).toBe('n1');
			expect(classeId).toBe('c1');
			expect(eleveId).toBe('e1');
		});

		it('should be usable in string operations', () => {
			const userId = createUserId('user-123');
			// Branded types should work in all string contexts
			expect(userId.startsWith('user-')).toBe(true);
			expect(userId.length).toBe(8);
			expect(`ID: ${userId}`).toBe('ID: user-123');
		});
	});
});
