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

import ReaderPersonChips from './ReaderPersonChips.svelte';
import type { components } from '$lib/generated/api';

type PersonSummaryDTO = components['schemas']['PersonSummaryDTO'];

afterEach(() => {
	cleanup();
});

const person1: PersonSummaryDTO = {
	id: 'aaaaaaaa-0000-0000-0000-000000000001',
	firstName: 'Anna',
	lastName: 'Müller',
	displayName: 'Anna Müller',
	documentCount: 23,
	personType: 'PERSON',
	familyMember: false
};

const person2: PersonSummaryDTO = {
	id: 'aaaaaaaa-0000-0000-0000-000000000002',
	firstName: 'Karl',
	lastName: 'Schmidt',
	displayName: 'Karl Schmidt',
	documentCount: 5,
	personType: 'PERSON',
	familyMember: false
};

describe('ReaderPersonChips', () => {
	it('renders a card for each person with correct href', async () => {
		render(ReaderPersonChips, { persons: [person1, person2] });
		const link1 = page.getByRole('link', { name: /Anna Müller/ });
		await expect
			.element(link1)
			.toHaveAttribute('href', '/persons/aaaaaaaa-0000-0000-0000-000000000001');
		const link2 = page.getByRole('link', { name: /Karl Schmidt/ });
		await expect
			.element(link2)
			.toHaveAttribute('href', '/persons/aaaaaaaa-0000-0000-0000-000000000002');
	});

	it('person card has min-h-[44px] touch target', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const link = page.getByRole('link', { name: /Anna Müller/ });
		const cls = ((await link.element()) as HTMLElement).className;
		expect(cls).toMatch(/min-h-\[44px\]/);
	});

	it('doc count renders as neutral chip with bg-muted', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const link = page.getByRole('link', { name: /Anna Müller/ });
		const el = (await link.element()) as HTMLElement;
		const chip = el.querySelector('[class*="bg-muted"]');
		expect(chip).not.toBeNull();
		expect(chip!.textContent).toContain('23');
	});

	it('doc count chip has rounded-full and border-line classes', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const link = page.getByRole('link', { name: /Anna Müller/ });
		const el = (await link.element()) as HTMLElement;
		const chip = el.querySelector('[class*="bg-muted"]');
		expect(chip).not.toBeNull();
		expect(chip!.className).toMatch(/rounded-full/);
		expect(chip!.className).toMatch(/border-line/);
	});

	it('person grid uses grid layout', async () => {
		render(ReaderPersonChips, { persons: [person1, person2] });
		const section = page.getByRole('region');
		const el = (await section.element()) as HTMLElement;
		const grid = el.querySelector('[class*="grid"]');
		expect(grid).not.toBeNull();
	});

	it('wrapper is a section with aria-label', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const section = page.getByRole('region');
		await expect.element(section).toBeInTheDocument();
		const label = ((await section.element()) as HTMLElement).getAttribute('aria-label');
		expect(label).toBeTruthy();
	});

	it('renders an "Alle Personen" link to /persons', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const allLink = page.getByRole('link', { name: /Alle Personen/i });
		await expect.element(allLink).toHaveAttribute('href', '/persons');
	});

	it('"Alle Personen" link has text-ink-2 class', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const allLink = page.getByRole('link', { name: /Alle Personen/i });
		const cls = ((await allLink.element()) as HTMLElement).className;
		expect(cls).toMatch(/text-ink-2/);
	});

	it('exposes a focus-visible ring on the "Alle Personen" link', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const allLink = page.getByRole('link', { name: /Alle Personen/i });
		const cls = ((await allLink.element()) as HTMLElement).className;
		expect(cls).toMatch(/focus-visible:ring-2/);
		expect(cls).toMatch(/focus-visible:ring-brand-navy/);
	});

	it('meets the 44px touch target on the "Alle Personen" link', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const allLink = page.getByRole('link', { name: /Alle Personen/i });
		const cls = ((await allLink.element()) as HTMLElement).className;
		expect(cls).toMatch(/min-h-\[44px\]/);
	});

	it('does not render h2 heading', async () => {
		render(ReaderPersonChips, { persons: [person1] });
		const heading = page.getByRole('heading', { level: 2 });
		await expect.element(heading).not.toBeInTheDocument();
	});

	it('renders empty state without person cards when persons array is empty', async () => {
		render(ReaderPersonChips, { persons: [] });
		const chips = page.getByRole('link', { name: /Müller|Schmidt/ });
		await expect.element(chips).not.toBeInTheDocument();
	});

	it('renders an empty-state message when persons array is empty', async () => {
		render(ReaderPersonChips, { persons: [] });
		const message = page.getByText(/Noch keine Personen im Archiv/i);
		await expect.element(message).toBeInTheDocument();
	});
});
