import { test, expect, type APIRequestContext } from '@playwright/test';

/**
 * Global /zeitstrahl timeline (#779). Runs against the real stack with the
 * seeded admin session (auth.setup). Covers the primary journey (nav → page,
 * timeline inside <main>) and the 320px no-overflow guarantee on a populated
 * timeline seeded with 25+char correspondent names (REQ-005).
 */

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 with long sender/receiver names so it lands on the timeline. */
async function seedDatedLetter(request: APIRequestContext) {
	const senderId = await createPerson(
		request,
		'Friedrich-Wilhelm',
		`Maximilian von Habsburg ${stamp()}`
	);
	const receiverId = await createPerson(
		request,
		'Maria-Magdalena',
		`Hohenzollern-Sigmaringen ${stamp()}`
	);

	const createRes = await request.post('/api/documents', {
		multipart: { title: `E2E Zeitstrahl Brief ${stamp()}` }
	});
	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: `E2E Zeitstrahl Brief ${stamp()}`,
			documentDate: '1915-06-15',
			metaDatePrecision: 'DAY',
			senderId,
			receiverIds: receiverId
		}
	});
	if (!put.ok()) throw new Error(`update document failed: ${put.status()}`);
}

test.describe('Zeitstrahl — global timeline (#779)', () => {
	test('nav link opens /zeitstrahl and the timeline lives in <main>', async ({ page }) => {
		await page.goto('/');
		await page.getByRole('navigation').getByRole('link', { name: 'Zeitstrahl' }).first().click();
		await expect(page).toHaveURL(/\/zeitstrahl$/);
		await expect(page.getByRole('heading', { level: 1, name: 'Zeitstrahl' })).toBeVisible();

		// The main landmark contains either the populated <ol> or the empty state.
		const main = page.getByRole('main');
		const ol = main.locator('ol');
		const empty = main.getByText('Noch keine Ereignisse.');
		await expect(async () => {
			const populated = (await ol.count()) > 0;
			const isEmpty = await empty.isVisible().catch(() => false);
			expect(populated || isEmpty).toBe(true);
		}).toPass();
	});

	test('no horizontal overflow at 320px with long correspondent names (REQ-005)', async ({
		page,
		request
	}) => {
		await seedDatedLetter(request);

		await page.setViewportSize({ width: 320, height: 900 });
		await page.goto('/zeitstrahl');

		// Populated: the seeded letter puts the timeline <ol> in the DOM.
		await expect(page.getByRole('main').locator('ol')).toHaveCount(1);

		const scrollWidth = await page.evaluate(() => document.body.scrollWidth);
		expect(scrollWidth).toBe(320);
	});
});
