import { describe, it, expect } from 'vitest';
import { avatarPalette, initials } from './avatar';

describe('avatarPalette', () => {
	it('returns the neutral palette for empty / nullish names', () => {
		expect(avatarPalette(null)).toContain('bg-gray-100');
		expect(avatarPalette(undefined)).toContain('bg-gray-100');
		expect(avatarPalette('')).toContain('bg-gray-100');
	});

	it('is deterministic for the same name', () => {
		// Same input, repeated calls AND a separately-constructed equal string — the palette
		// must be a pure function of the name's characters, not of identity or call order.
		expect(avatarPalette('Alice')).toBe(avatarPalette('Alice'));
		expect(avatarPalette('Alice')).toBe(avatarPalette('Ali' + 'ce'));
		expect(avatarPalette('Zoë Müller')).toBe(avatarPalette('Zoë Müller'));
	});

	it('returns a real palette entry (not neutral) for a non-empty name', () => {
		expect(avatarPalette('Bob')).toMatch(/bg-(blue|purple|green|amber|rose|teal)-100/);
	});

	it('maps different names to different palette entries', () => {
		// Without this, `name => name ? PALETTE[0] : NEUTRAL` (i.e. the hash loop deleted)
		// passes every other test in this file — the palette would be a constant and every
		// avatar in the app would render the same colour.
		expect(avatarPalette('Alice')).not.toBe(avatarPalette('Bob'));
	});

	it('spreads names across the whole palette, not just one bucket', () => {
		const names = [
			'Alice',
			'Bob',
			'Carol',
			'Dave',
			'Erin',
			'Frank',
			'Grace',
			'Heidi',
			'Ivan',
			'Judy',
			'Mallory',
			'Niaj',
			'Olivia',
			'Peggy',
			'Rupert',
			'Sybil',
			'Trent',
			'Victor',
			'Walter',
			'Xena'
		];
		const distinct = new Set(names.map((n) => avatarPalette(n)));
		// 6 colours in the palette; 20 names must land on more than a couple of them. This
		// catches a hash that collapses (e.g. always returns index 0, or ignores all but the
		// first character in a way that clusters).
		expect(distinct.size).toBeGreaterThanOrEqual(4);
	});
});

describe('initials', () => {
	it('returns "?" for empty / nullish / whitespace-only names', () => {
		expect(initials(null)).toBe('?');
		expect(initials(undefined)).toBe('?');
		expect(initials('')).toBe('?');
		expect(initials('   ')).toBe('?');
	});

	it('uses the first letter (uppercased) for a single word', () => {
		expect(initials('alice')).toBe('A');
	});

	it('uses the first letters of the first two words', () => {
		expect(initials('Alice Bob Carol')).toBe('AB');
	});

	it('collapses runs of whitespace between words', () => {
		expect(initials('  john   doe ')).toBe('JD');
	});
});
