import AxeBuilder from '@axe-core/playwright';
import { test, expect, type APIRequestContext } from '@playwright/test';

/**
 * Global /zeitstrahl layer filter (#780). Runs against the real stack with the
 * seeded admin session (auth.setup). Covers the primary journey (hide the
 * Letters layer → letter cards vanish + the trigger reports one active filter →
 * reset restores everything) and a 375px axe pass with the collapsible open in
 * both light and dark mode.
 *
 * #779 (the /zeitstrahl route) is merged, so this spec is NOT skipped. Per
 * e2e/CLAUDE.md, E2E is not yet wired into CI — this axe gate runs locally only
 * for now.
 */

const stamp = () => new Date().toISOString().replace(/[^0-9]/g, '');

async function createPerson(request: APIRequestContext, firstName: string, lastName: string) {
	const res = await request.post('/api/persons', {
		data: { personType: 'PERSON', firstName, lastName }
	});
	if (!res.ok()) throw new Error(`create person failed: ${res.status()}`);
	return (await res.json()).id as string;
}

/** Seeds one dated letter so the timeline has content (and a LetterCard to hide). */
async function seedDatedLetter(request: APIRequestContext, isoDate: string, title: string) {
	const senderId = await createPerson(request, 'Filter-Test', `Absender ${stamp()}`);
	const receiverId = await createPerson(request, 'Filter-Test', `Empfaenger ${stamp()}`);

	const createRes = await request.post('/api/documents', { multipart: { title } });
	if (!createRes.ok()) throw new Error(`create document failed: ${createRes.status()}`);
	const docId = (await createRes.json()).id as string;

	const put = await request.put(`/api/documents/${docId}`, {
		multipart: {
			title,
			documentDate: isoDate,
			metaDatePrecision: 'DAY',
			senderId,
			receiverIds: receiverId
		}
	});
	if (!put.ok()) throw new Error(`update document failed: ${put.status()}`);
}

test.describe('Zeitstrahl — layer filter (#780)', () => {
	test('hiding the Letters layer removes letter cards and reports the active count; reset restores', async ({
		page,
		request
	}) => {
		// A sparse year keeps the seeded letter an individual card (not a dense strip).
		const title = `E2E Filter Brief ${stamp()}`;
		await seedDatedLetter(request, '1903-03-03', title);

		await page.goto('/zeitstrahl');
		await page.waitForSelector('[data-hydrated]');
		await expect(page.getByText(title)).toBeVisible();

		await page.getByTestId('timeline-filter-trigger').click();
		await page.getByTestId('timeline-filter-letters').click();

		await expect(page.getByText(title)).toHaveCount(0);
		await expect(page.getByTestId('timeline-filter-trigger')).toContainText('1 aktiv');

		await page.getByTestId('timeline-filter-reset').click();
		await expect(page.getByText(title)).toBeVisible();
	});

	test('no wcag2a/wcag2aa violations at 375px with the filter bar open (light + dark)', async ({
		page,
		request
	}) => {
		await seedDatedLetter(request, '1915-06-15', `E2E Filter A11y ${stamp()}`);

		await page.setViewportSize({ width: 375, height: 800 });
		await page.goto('/zeitstrahl');
		await page.waitForSelector('[data-hydrated]');

		// Open the collapsible so axe scans the toggles, not just the trigger.
		await page.getByTestId('timeline-filter-trigger').click();
		await expect(page.getByTestId('timeline-filter-personal')).toBeVisible();

		const scan = () => new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']).analyze();

		const light = await scan();
		expect(light.violations, JSON.stringify(light.violations, null, 2)).toEqual([]);

		await page.evaluate(() => document.documentElement.setAttribute('data-theme', 'dark'));
		const dark = await scan();
		expect(dark.violations, JSON.stringify(dark.violations, null, 2)).toEqual([]);
	});
});
