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

vi.mock('$app/navigation', () => ({ goto: vi.fn() }));
vi.mock('$app/state', () => ({ navigating: { to: null } }));

import Page from './+page.svelte';
import type { PageData } from './$types';

afterEach(() => {
	cleanup();
	vi.clearAllMocks();
});

function person(id: string, displayName: string) {
	return {
		id,
		firstName: displayName.split(' ')[0] ?? displayName,
		lastName: displayName.split(' ').slice(1).join(' ') || 'X',
		displayName,
		personType: 'PERSON'
	};
}

function makeData(overrides: Partial<PageData> = {}): PageData {
	return {
		geschichten: [],
		personFilters: [],
		documentFilter: null,
		canBlogWrite: false,
		...overrides
	} as unknown as PageData;
}

describe('geschichten page — multi-person filter chips', () => {
	it('renders one chip per person in personFilters', async () => {
		render(Page, {
			data: makeData({
				personFilters: [person('a', 'Anna A'), person('b', 'Bertha B')] as PageData['personFilters']
			})
		});

		await expect
			.element(page.getByRole('button', { name: /Anna A aus Filter entfernen/ }))
			.toBeVisible();
		await expect
			.element(page.getByRole('button', { name: /Bertha B aus Filter entfernen/ }))
			.toBeVisible();
	});

	it('renders the "All" pill in pressed state when no filters are active', async () => {
		render(Page, { data: makeData() });
		await expect
			.element(page.getByRole('button', { name: 'Alle' }))
			.toHaveAttribute('aria-pressed', 'true');
	});

	it('renders the "All" pill in unpressed state when at least one filter is active', async () => {
		render(Page, {
			data: makeData({
				personFilters: [person('a', 'Anna A')] as PageData['personFilters']
			})
		});
		await expect
			.element(page.getByRole('button', { name: 'Alle' }))
			.toHaveAttribute('aria-pressed', 'false');
	});

	it('clicking × on a chip removes only that person from the URL', async () => {
		const { goto } = await import('$app/navigation');
		vi.mocked(goto).mockClear();

		// Seed window.location so the chip-removal logic builds the new URL deterministically.
		const originalHref = window.location.href;
		window.history.replaceState({}, '', '/geschichten?personId=a&personId=b');

		render(Page, {
			data: makeData({
				personFilters: [person('a', 'Anna A'), person('b', 'Bertha B')] as PageData['personFilters']
			})
		});

		await page.getByRole('button', { name: /Anna A aus Filter entfernen/ }).click();

		expect(goto).toHaveBeenCalledOnce();
		const url = vi.mocked(goto).mock.calls[0][0] as string;
		expect(url).toContain('personId=b');
		expect(url).not.toContain('personId=a');

		window.history.replaceState({}, '', originalHref);
	});

	it('shows the "+ Person wählen" button even when filters are already active', async () => {
		render(Page, {
			data: makeData({
				personFilters: [person('a', 'Anna A')] as PageData['personFilters']
			})
		});
		await expect.element(page.getByRole('button', { name: /Person wählen/ })).toBeVisible();
	});

	it('renders all filter pills with a 44px touch target (h-11)', async () => {
		render(Page, {
			data: makeData({
				personFilters: [person('a', 'Anna A')] as PageData['personFilters']
			})
		});

		// All three pill variants must use h-11 (44px) per the senior-author touch-target rule
		const all = page.getByRole('button', { name: 'Alle' });
		const chip = page.getByRole('button', { name: /Anna A aus Filter entfernen/ });
		const add = page.getByRole('button', { name: /Person wählen/ });

		const allEl = (await all.element()) as HTMLElement;
		const chipEl = (await chip.element()) as HTMLElement;
		const addEl = (await add.element()) as HTMLElement;

		expect(allEl.className).toContain('h-11');
		expect(chipEl.className).toContain('h-11');
		expect(addEl.className).toContain('h-11');
	});
});
