import { describe, it, expect, vi, afterEach } from 'vitest';
import { cleanup, render } from 'vitest-browser-svelte';
import WhoWhenSection from './WhoWhenSection.svelte';

afterEach(cleanup);

describe('WhoWhenSection — date input behavior', () => {
	it('marks the date input as invalid when input has text but no valid ISO', async () => {
		render(WhoWhenSection, {});

		const dateInput = document.querySelector('input#documentDate') as HTMLInputElement;
		dateInput.value = '32.13';
		dateInput.dispatchEvent(new Event('input', { bubbles: true }));

		await vi.waitFor(() => {
			// Invalid → border-red-400 class
			expect(dateInput.className).toContain('border-red-400');
			expect(document.querySelector('#documentDate-error')).not.toBeNull();
		});
	});

	it('does not show the error before the user has typed', async () => {
		render(WhoWhenSection, {});

		const error = document.querySelector('#documentDate-error');
		expect(error).toBeNull();
	});

	it('updates the hidden ISO input when typing a valid German date', async () => {
		render(WhoWhenSection, {});

		const dateInput = document.querySelector('input#documentDate') as HTMLInputElement;
		dateInput.value = '15.03.2024';
		dateInput.dispatchEvent(new Event('input', { bubbles: true }));

		await vi.waitFor(() => {
			const hidden = document.querySelector(
				'input[name="documentDate"][type="hidden"]'
			) as HTMLInputElement;
			expect(hidden.value).toBe('2024-03-15');
		});
	});

	it('renders the location input outside editMode with initialLocation', async () => {
		render(WhoWhenSection, { editMode: false, initialLocation: 'Hamburg' });

		const loc = document.querySelector('input#location') as HTMLInputElement;
		expect(loc.value).toBe('Hamburg');
	});

	it('hides the location input in editMode', async () => {
		render(WhoWhenSection, { editMode: true });

		const loc = document.querySelector('input#location');
		expect(loc).toBeNull();
	});

	it('shows the FieldLabelBadge for receivers in editMode', async () => {
		render(WhoWhenSection, { editMode: true });

		// FieldLabelBadge with variant=additive is rendered (just check the heading area)
		const labels = Array.from(document.querySelectorAll('p, label')).filter((el) =>
			/empfänger/i.test(el.textContent ?? '')
		);
		expect(labels.length).toBeGreaterThan(0);
	});

	it('renders the date asterisk indicator (required field)', async () => {
		render(WhoWhenSection, {});

		const label = document.querySelector('label[for="documentDate"]');
		expect(label?.textContent).toContain('*');
	});
});

describe('WhoWhenSection — precision controls', () => {
	it('renders a labelled precision select', async () => {
		render(WhoWhenSection, {});

		const label = document.querySelector('label[for="documentDatePrecision"]');
		const select = document.querySelector('select#documentDatePrecision[name="metaDatePrecision"]');
		expect(label).not.toBeNull();
		expect(select).not.toBeNull();
	});

	it('hides the end-date field unless precision is RANGE', async () => {
		render(WhoWhenSection, { precision: 'DAY' });
		expect(document.querySelector('input#documentDateEnd')).toBeNull();
	});

	it('reveals the end-date field when precision is RANGE', async () => {
		render(WhoWhenSection, { precision: 'RANGE' });
		expect(document.querySelector('input#documentDateEnd')).not.toBeNull();
	});

	it('never renders the raw cell, and never re-submits it via a hidden input', async () => {
		render(WhoWhenSection, {});
		// The confusing "Originaltext" line is gone …
		expect(document.querySelector('[data-testid="who-when-raw"]')).toBeNull();
		// … and editing no longer round-trips metaDateRaw to the backend.
		expect(document.querySelector('input[name="metaDateRaw"]')).toBeNull();
	});
});

describe('WhoWhenSection — end-before-start inline validation (#678)', () => {
	it('shows an inline error on the end-date field when end is before start (AC1)', async () => {
		render(WhoWhenSection, {
			precision: 'RANGE',
			dateIso: '1917-01-11',
			endDateIso: '1917-01-10'
		});

		const end = document.querySelector('input#documentDateEnd') as HTMLInputElement;
		await vi.waitFor(() => {
			expect(document.querySelector('#documentDate-end-error')).not.toBeNull();
			expect(end.getAttribute('aria-invalid')).toBe('true');
			expect(end.className).toContain('border-red-400');
		});
	});

	it('clears the inline error once the end date is corrected, without reload (AC5)', async () => {
		render(WhoWhenSection, {
			precision: 'RANGE',
			dateIso: '1917-01-11',
			endDateIso: '1917-01-10'
		});

		await vi.waitFor(() =>
			expect(document.querySelector('#documentDate-end-error')).not.toBeNull()
		);

		const end = document.querySelector('input#documentDateEnd') as HTMLInputElement;
		end.value = '12.01.1917'; // now after the start
		end.dispatchEvent(new Event('input', { bubbles: true }));

		await vi.waitFor(() => {
			expect(document.querySelector('#documentDate-end-error')).toBeNull();
			expect(end.getAttribute('aria-invalid')).not.toBe('true');
		});
	});

	it('does not show the inline error when precision is not RANGE', async () => {
		render(WhoWhenSection, {
			precision: 'DAY',
			dateIso: '1917-01-11',
			endDateIso: '1917-01-10'
		});

		expect(document.querySelector('#documentDate-end-error')).toBeNull();
	});
});
