import { describe, it, expect } from 'vitest';
import { getInitials, abbreviateName, formatXsMeta, personAvatarColor } from './personFormat';
import { formatDate } from '$lib/shared/utils/date';

// ─── getInitials ─────────────────────────────────────────────────────────────

describe('getInitials', () => {
	it('returns first chars of first and last word uppercased', () => {
		expect(getInitials('Marcel Raddatz')).toBe('MR');
	});

	it('returns single char for a single-word name', () => {
		expect(getInitials('Raddatz')).toBe('R');
	});

	it('returns empty string for an empty name', () => {
		expect(getInitials('')).toBe('');
	});

	it('splits on whitespace only — hyphenated first word counts as one', () => {
		expect(getInitials('Anna-Maria Raddatz')).toBe('AR');
	});

	it('ignores extra whitespace between words', () => {
		expect(getInitials('  Karl   Raddatz  ')).toBe('KR');
	});
});

// ─── abbreviateName ──────────────────────────────────────────────────────────

describe('abbreviateName', () => {
	it('abbreviates first name to initial + last name', () => {
		expect(abbreviateName({ firstName: 'Karl', lastName: 'Raddatz' })).toBe('K. Raddatz');
	});

	it('returns single name as-is when no last name', () => {
		expect(abbreviateName({ firstName: 'Elfriede', lastName: '' })).toBe('Elfriede');
	});

	it('preserves hyphenated last name', () => {
		expect(abbreviateName({ firstName: 'Karl', lastName: 'Müller-Schmidt' })).toBe(
			'K. Müller-Schmidt'
		);
	});

	it('handles leading/trailing whitespace in names', () => {
		expect(abbreviateName({ firstName: '  Karl  ', lastName: '  Raddatz  ' })).toBe('K. Raddatz');
	});
});

// ─── formatXsMeta ────────────────────────────────────────────────────────────

type Doc = {
	sender?: { firstName: string; lastName: string } | null;
	receivers?: { firstName: string; lastName: string }[];
	documentDate?: string | null;
};

describe('formatXsMeta', () => {
	const sender = { firstName: 'Karl', lastName: 'Raddatz' };
	const receiver1 = { firstName: 'Elfriede', lastName: 'Raddatz' };
	const receiver2 = { firstName: 'Anna', lastName: 'Müller' };
	const receiver3 = { firstName: 'Hans', lastName: 'Schmidt' };

	it('formats sender with no receivers and date', () => {
		const doc: Doc = { sender, receivers: [], documentDate: '1943-12-24' };
		expect(formatXsMeta(doc)).toBe('K.Raddatz · 24.12.1943');
	});

	it('formats sender with one receiver and date', () => {
		const doc: Doc = { sender, receivers: [receiver1], documentDate: '1943-12-24' };
		expect(formatXsMeta(doc)).toBe('K.Raddatz → E.Raddatz · 24.12.1943');
	});

	it('formats sender with three receivers showing +2', () => {
		const doc: Doc = {
			sender,
			receivers: [receiver1, receiver2, receiver3],
			documentDate: '1943-12-24'
		};
		expect(formatXsMeta(doc)).toBe('K.Raddatz → E.Raddatz +2 · 24.12.1943');
	});

	it('formats without sender', () => {
		const doc: Doc = { sender: null, receivers: [receiver1], documentDate: '1943-12-24' };
		expect(formatXsMeta(doc)).toBe('E.Raddatz · 24.12.1943');
	});

	it('formats without date', () => {
		const doc: Doc = { sender, receivers: [], documentDate: null };
		expect(formatXsMeta(doc)).toBe('K.Raddatz');
	});

	it('formats with no sender and no date', () => {
		const doc: Doc = { sender: null, receivers: [receiver1], documentDate: null };
		expect(formatXsMeta(doc)).toBe('E.Raddatz');
	});
});

// ─── personAvatarColor ───────────────────────────────────────────────────────

const PALETTE = ['#012851', '#5A3080', '#007596', '#2A6040', '#803020'];

describe('personAvatarColor', () => {
	it('returns a value from the palette', () => {
		expect(PALETTE).toContain(personAvatarColor('abc'));
	});

	it('is deterministic — same id always returns same color', () => {
		const id = '550e8400-e29b-41d4-a716-446655440000';
		expect(personAvatarColor(id)).toBe(personAvatarColor(id));
	});

	it('all 5 palette entries are reachable across 1000 random UUIDs', () => {
		const seen = new Set<string>();
		for (let i = 0; i < 1000; i++) {
			seen.add(personAvatarColor(crypto.randomUUID()));
		}
		expect(seen.size).toBe(5);
	});
});

// ─── formatDate ──────────────────────────────────────────────────────────────

describe('formatDate', () => {
	it('formats short date as dd.mm.yyyy', () => {
		expect(formatDate('1943-12-24', 'short')).toBe('24.12.1943');
	});

	it('formats long date with German month name', () => {
		expect(formatDate('1943-12-24', 'long')).toBe('24. Dezember 1943');
	});

	it('does not shift Dec 31 to Jan 1 (UTC off-by-one guard)', () => {
		expect(formatDate('1943-12-31', 'short')).toBe('31.12.1943');
	});

	it('does not shift Jan 1 to Dec 31 (UTC off-by-one guard)', () => {
		expect(formatDate('1944-01-01', 'short')).toBe('01.01.1944');
	});
});
