import { describe, it, expect, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import * as m from '$lib/paraglide/messages.js';
import EventPill from './EventPill.svelte';
import { timelineDateLabel } from './dateLabel';
import { makeEntry } from './test-factories';

afterEach(() => cleanup());

const EVENT_ID = '33333333-3333-3333-3333-333333333333';

function derived(derivedType: 'BIRTH' | 'DEATH' | 'MARRIAGE', title: string) {
	return makeEntry({
		kind: 'EVENT',
		derived: true,
		derivedType,
		title,
		senderName: '',
		receiverName: '',
		precision: 'YEAR',
		eventDate: '1914-01-01',
		documentId: undefined
	});
}

describe('EventPill', () => {
	it('renders a derived marriage as ⚭ + "Heirat" + title (REQ-007)', () => {
		render(EventPill, { entry: derived('MARRIAGE', 'Heirat: Karl & Elfriede') });
		expect(document.body.textContent).toContain('⚭');
		expect(document.body.textContent).toContain('Heirat');
		expect(document.body.textContent).toContain('Heirat: Karl & Elfriede');
	});

	it('renders a derived birth as * + "Geburt" (REQ-007)', () => {
		render(EventPill, { entry: derived('BIRTH', 'Geburt: Hans') });
		expect(document.body.textContent).toContain('*');
		expect(document.body.textContent).toContain('Geburt');
	});

	it('renders a derived death as † + "Tod" (REQ-007)', () => {
		render(EventPill, { entry: derived('DEATH', 'Tod: Karl') });
		expect(document.body.textContent).toContain('†');
		expect(document.body.textContent).toContain('Tod');
	});

	it('wraps the glyph aria-hidden with an sr-only label sibling (REQ-018)', () => {
		render(EventPill, { entry: derived('BIRTH', 'Geburt: Hans') });
		const hidden = document.querySelector('[aria-hidden="true"]');
		expect(hidden?.textContent).toBe('*');
		const srOnly = document.querySelector('.sr-only');
		expect(srOnly?.textContent).toBe('Geburt');
	});

	it('shows an edit affordance for a curated PERSONAL event when canWrite is true (REQ-005)', () => {
		render(EventPill, {
			canWrite: true,
			entry: makeEntry({
				kind: 'EVENT',
				derived: false,
				type: 'PERSONAL',
				eventId: EVENT_ID,
				title: 'Auswanderung',
				senderName: '',
				receiverName: '',
				documentId: undefined
			})
		});
		const edit = document.querySelector('[data-testid="event-edit"]') as HTMLAnchorElement | null;
		expect(edit).not.toBeNull();
		expect(edit?.getAttribute('href')).toBe(`/zeitstrahl/events/${EVENT_ID}/edit`);
	});

	it('renders no edit affordance for a curated PERSONAL event when canWrite is false (REQ-007)', () => {
		render(EventPill, {
			canWrite: false,
			entry: makeEntry({
				kind: 'EVENT',
				derived: false,
				type: 'PERSONAL',
				eventId: EVENT_ID,
				title: 'Auswanderung',
				senderName: '',
				receiverName: '',
				documentId: undefined
			})
		});
		expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
	});

	it('renders no edit affordance when the canWrite prop is omitted (gate-closed default) (REQ-007)', () => {
		render(EventPill, {
			entry: makeEntry({
				kind: 'EVENT',
				derived: false,
				type: 'PERSONAL',
				eventId: EVENT_ID,
				title: 'Auswanderung',
				senderName: '',
				receiverName: '',
				documentId: undefined
			})
		});
		expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
	});

	it('shows no edit affordance when eventId is null even with canWrite (REQ-008)', () => {
		render(EventPill, {
			canWrite: true,
			entry: makeEntry({
				kind: 'EVENT',
				derived: false,
				type: 'PERSONAL',
				eventId: undefined,
				title: 'Auswanderung',
				senderName: '',
				receiverName: '',
				documentId: undefined
			})
		});
		expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
	});

	it('shows no edit affordance for a derived event even with canWrite (REQ-008)', () => {
		render(EventPill, { canWrite: true, entry: derived('MARRIAGE', 'Heirat') });
		expect(document.querySelector('[data-testid="event-edit"]')).toBeNull();
	});

	it('appends the "abgeleitet" provenance token to a derived pill subtitle (REQ-007)', () => {
		const entry = derived('BIRTH', 'Geburt: Hans');
		const date = timelineDateLabel(entry.eventDate, entry.precision, entry.eventDateEnd);
		render(EventPill, { entry });
		expect(document.body.textContent).toContain(`${date} · ${m.timeline_provenance_derived()}`);
	});

	it('appends the "kuratiert" provenance token to a curated PERSONAL pill subtitle (REQ-007)', () => {
		const entry = makeEntry({
			kind: 'EVENT',
			derived: false,
			type: 'PERSONAL',
			eventId: EVENT_ID,
			title: 'Auswanderung',
			senderName: '',
			receiverName: '',
			precision: 'YEAR',
			eventDate: '1924-01-01',
			documentId: undefined
		});
		const date = timelineDateLabel(entry.eventDate, entry.precision, entry.eventDateEnd);
		render(EventPill, { entry });
		expect(document.body.textContent).toContain(`${date} · ${m.timeline_provenance_curated()}`);
	});

	it('never shows the spec-sheet-only "persönlich"/"SEASON" tokens (REQ-007)', () => {
		render(EventPill, { entry: derived('BIRTH', 'Geburt: Hans') });
		expect(document.body.textContent).not.toContain('persönlich');
		expect(document.body.textContent).not.toContain('SEASON');
	});

	it('still shows the provenance token when the event has no date label (REQ-007)', () => {
		// An undated / UNKNOWN-precision event (e.g. in the undated bucket) yields a
		// null dateLabel; provenance must not be gated behind the date.
		const entry = makeEntry({
			kind: 'EVENT',
			derived: true,
			derivedType: 'BIRTH',
			title: 'Geburt: Hans',
			senderName: '',
			receiverName: '',
			precision: 'UNKNOWN',
			eventDate: undefined,
			documentId: undefined
		});
		expect(timelineDateLabel(entry.eventDate, entry.precision, entry.eventDateEnd)).toBeNull();
		render(EventPill, { entry });
		expect(document.body.textContent).toContain(m.timeline_provenance_derived());
	});
});
