import { describe, expect, it } from 'vitest';
import { formatLifeDate, formatLifeDateRange } from './personLifeDates';

// Delegates all precision rendering to formatDocumentDate — these tests pin the
// composition (glyphs, dash, empty sides) and one rendering per precision so a
// regression in the delegation is caught here, not on a person card.
describe('formatLifeDateRange', () => {
	describe('both dates (de default)', () => {
		it('renders DAY precision as full dates', () => {
			expect(formatLifeDateRange('1901-03-14', 'DAY', '1944-11-02', 'DAY')).toBe(
				'* 14. März 1901 – † 2. November 1944'
			);
		});

		it('renders MONTH precision as month + year', () => {
			expect(formatLifeDateRange('1901-03-01', 'MONTH', '1944-11-01', 'MONTH')).toBe(
				'* März 1901 – † November 1944'
			);
		});

		it('renders YEAR precision as bare years', () => {
			expect(formatLifeDateRange('1901-01-01', 'YEAR', '1944-01-01', 'YEAR')).toBe(
				'* 1901 – † 1944'
			);
		});

		it('renders mixed precisions per side', () => {
			expect(formatLifeDateRange('1901-03-14', 'DAY', '1944-01-01', 'YEAR')).toBe(
				'* 14. März 1901 – † 1944'
			);
		});

		it('renders APPROX precision with the ca. prefix (legacy imports)', () => {
			expect(formatLifeDateRange('1901-01-01', 'APPROX', '1944-01-01', 'APPROX')).toBe(
				'* ca. 1901 – † ca. 1944'
			);
		});
	});

	describe('single sides and empty states', () => {
		it('renders birth only without dash or dagger', () => {
			expect(formatLifeDateRange('1901-03-14', 'DAY', null, null)).toBe('* 14. März 1901');
		});

		it('renders death only without dash or asterisk', () => {
			expect(formatLifeDateRange(null, null, '1944-11-02', 'DAY')).toBe('† 2. November 1944');
		});

		it('renders YEAR birth only', () => {
			expect(formatLifeDateRange('1882-01-01', 'YEAR', null, null)).toBe('* 1882');
		});

		it('renders APPROX death only', () => {
			expect(formatLifeDateRange(null, null, '1944-01-01', 'APPROX')).toBe('† ca. 1944');
		});

		it('returns empty string when both dates are null', () => {
			expect(formatLifeDateRange(null, null, null, null)).toBe('');
		});

		it('returns empty string when both dates are null even with UNKNOWN precisions', () => {
			expect(formatLifeDateRange(null, 'UNKNOWN', null, 'UNKNOWN')).toBe('');
		});

		it('falls back to YEAR rendering when a precision is missing', () => {
			expect(formatLifeDateRange('1901-01-01', null, null, null)).toBe('* 1901');
		});
	});

	describe('locales (German-month-leak guard)', () => {
		it('renders DAY precision in English', () => {
			expect(formatLifeDateRange('1901-03-14', 'DAY', null, null, 'en')).toBe('* March 14, 1901');
		});

		it('renders MONTH precision in English', () => {
			expect(formatLifeDateRange('1901-03-01', 'MONTH', null, null, 'en')).toBe('* March 1901');
		});

		it('renders DAY precision in Spanish', () => {
			expect(formatLifeDateRange('1901-03-14', 'DAY', null, null, 'es')).toBe(
				'* 14 de marzo de 1901'
			);
		});

		it('renders MONTH precision in Spanish', () => {
			expect(formatLifeDateRange('1901-03-01', 'MONTH', null, null, 'es')).toBe('* marzo de 1901');
		});
	});
});

// Single-date helper for components that must keep the * / † glyphs in their own
// aria-hidden markup (PersonCard, PersonHoverCard) instead of in the string.
describe('formatLifeDate', () => {
	it('renders a DAY-precision date without any glyph', () => {
		expect(formatLifeDate('1901-03-14', 'DAY')).toBe('14. März 1901');
	});

	it('renders an APPROX-precision date (legacy imports)', () => {
		expect(formatLifeDate('1901-01-01', 'APPROX')).toBe('ca. 1901');
	});

	it('falls back to YEAR rendering when precision is missing', () => {
		expect(formatLifeDate('1901-01-01', null)).toBe('1901');
	});

	it('returns empty string for a null date', () => {
		expect(formatLifeDate(null, 'DAY')).toBe('');
	});

	it('renders in the requested locale', () => {
		expect(formatLifeDate('1901-03-14', 'DAY', 'en')).toBe('March 14, 1901');
	});
});
