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

afterEach(cleanup);

const personPersonal = {
	id: 'p1',
	personType: 'PERSON',
	title: 'Frau Dr.',
	firstName: 'Anna',
	lastName: 'Schmidt',
	alias: 'Anni',
	birthYear: 1899 as number | null,
	deathYear: 1972 as number | null,
	notes: 'Wohnte in Berlin.'
};

const personInstitution = {
	id: 'p2',
	personType: 'INSTITUTION',
	title: null,
	firstName: null,
	lastName: 'Acme GmbH',
	alias: null,
	birthYear: null,
	deathYear: null,
	notes: null
};

describe('PersonEditForm', () => {
	it('renders the firstName input for the PERSON personType', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		await expect.element(page.getByLabelText(/vorname/i)).toBeVisible();
	});

	it('renders the title input only for the PERSON personType', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		await expect.element(page.getByLabelText(/titel/i)).toBeVisible();
	});

	it('hides the firstName / title / alias / year fields for INSTITUTION', async () => {
		render(PersonEditForm, { props: { person: personInstitution } });

		await expect.element(page.getByLabelText(/vorname/i)).not.toBeInTheDocument();
		await expect.element(page.getByLabelText(/^titel$/i)).not.toBeInTheDocument();
		await expect.element(page.getByLabelText(/rufname/i)).not.toBeInTheDocument();
		await expect.element(page.getByLabelText(/geburtsjahr/i)).not.toBeInTheDocument();
		await expect.element(page.getByLabelText(/todesjahr/i)).not.toBeInTheDocument();
	});

	it('uses the "Nachname" label for PERSON', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		await expect.element(page.getByLabelText(/nachname \*/i)).toBeVisible();
	});

	it('uses the "Name" label for INSTITUTION', async () => {
		render(PersonEditForm, { props: { person: personInstitution } });

		await expect.element(page.getByLabelText(/^name \*$/i)).toBeVisible();
	});

	it('hydrates inputs from the person prop', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		const firstName = (await page.getByLabelText(/vorname/i).element()) as HTMLInputElement;
		const lastName = (await page.getByLabelText(/nachname/i).element()) as HTMLInputElement;
		const alias = (await page.getByLabelText(/rufname/i).element()) as HTMLInputElement;
		const title = (await page.getByLabelText(/^titel/i).element()) as HTMLInputElement;
		expect(firstName.value).toBe('Anna');
		expect(lastName.value).toBe('Schmidt');
		expect(alias.value).toBe('Anni');
		expect(title.value).toBe('Frau Dr.');
	});

	it('renders birthYear and deathYear inputs with prior values', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		const birthYear = (await page.getByLabelText(/geburtsjahr/i).element()) as HTMLInputElement;
		const deathYear = (await page.getByLabelText(/todesjahr/i).element()) as HTMLInputElement;
		expect(birthYear.value).toBe('1899');
		expect(deathYear.value).toBe('1972');
	});

	it('renders the notes textarea pre-filled with prior content', async () => {
		render(PersonEditForm, { props: { person: personPersonal } });

		const notes = (await page.getByLabelText(/notizen/i).element()) as HTMLTextAreaElement;
		expect(notes.value).toBe('Wohnte in Berlin.');
	});

	it('falls back to PERSON when an unknown personType is supplied', async () => {
		render(PersonEditForm, {
			props: { person: { ...personPersonal, personType: 'NOT_A_TYPE' } }
		});

		await expect.element(page.getByLabelText(/vorname/i)).toBeVisible();
	});

	it('renders empty inputs when nullable fields are null', async () => {
		render(PersonEditForm, {
			props: { person: { ...personPersonal, title: null, alias: null, birthYear: null } }
		});

		const title = (await page.getByLabelText(/^titel/i).element()) as HTMLInputElement;
		const alias = (await page.getByLabelText(/rufname/i).element()) as HTMLInputElement;
		const birthYear = (await page.getByLabelText(/geburtsjahr/i).element()) as HTMLInputElement;
		expect(title.value).toBe('');
		expect(alias.value).toBe('');
		expect(birthYear.value).toBe('');
	});
});
