import { test, expect } from '@playwright/test';
import {
	seedBilateralPair,
	cleanupBilateralPair,
	type BilateralPair
} from './fixtures/bilateral-correspondence';

// Visual + structural coverage for the new briefwechsel row layout.
//
// Seeds a bilateral correspondence pair via the shared fixture so the page
// reaches the row state. The structural test asserts that a
// ConversationThumbnail tile AND the DistributionBar render — regressions
// that silently drop to the hero or break the {#each} wiring fail here.
//
// Snapshot assertions are gated on the VISUAL env flag because they need
// pre-captured baselines (see `playwright test --update-snapshots` to
// regenerate after intentional UI changes). CI can opt in via VISUAL=1.
const VISUAL = process.env.VISUAL === '1';

let pair: BilateralPair;

test.describe('Briefwechsel — thumbnail-row layout', () => {
	test.beforeAll(async ({ request }) => {
		pair = await seedBilateralPair(request, 'Visual');
	});

	test.afterAll(async ({ request }) => {
		await cleanupBilateralPair(request, pair);
	});

	async function openBilateral(page: import('@playwright/test').Page) {
		await page.goto(
			`/briefwechsel?senderId=${encodeURIComponent(pair.senderId)}&receiverId=${encodeURIComponent(pair.receiverId)}`
		);
		await page.waitForSelector('[data-hydrated]');
		// Parity with the a11y spec: fail loudly if we ever end up on the hero
		// instead of the row layout.
		await expect(page.getByTestId('conv-person-bar')).toBeVisible();
	}

	test('renders a ConversationThumbnail tile and the DistributionBar', async ({ page }) => {
		await openBilateral(page);

		// Tile appears for the seeded document
		await expect(page.locator('[data-testid="conv-thumb-tile"]').first()).toBeVisible();

		// DistributionBar is present (role=img with a descriptive aria-label)
		const bar = page.locator('[role="img"]');
		await expect(bar).toBeVisible();
		const label = (await bar.getAttribute('aria-label')) ?? '';
		expect(label.length).toBeGreaterThan(0);
	});

	// Visual regression — one snapshot per (viewport × theme). Tolerance stays
	// generous (maxDiffPixels: 100) so antialiasing jitter doesn't flip them on
	// unrelated runs; genuine layout changes are still caught because the
	// thumbnail tile and distribution bar dominate the frame.
	test.describe('snapshots', () => {
		test.skip(!VISUAL, 'VISUAL=1 required to compare baselines');

		for (const viewport of [
			{ name: 'mobile', width: 375, height: 812 },
			{ name: 'tablet', width: 768, height: 1024 },
			{ name: 'desktop', width: 1280, height: 800 }
		] as const) {
			for (const theme of ['light', 'dark'] as const) {
				test(`${viewport.name} / ${theme}`, async ({ page }) => {
					await page.setViewportSize({ width: viewport.width, height: viewport.height });
					await page.emulateMedia({ colorScheme: theme });
					await openBilateral(page);
					await expect(page).toHaveScreenshot(`briefwechsel-${viewport.name}-${theme}.png`, {
						maxDiffPixels: 100,
						fullPage: true
					});
				});
			}
		}
	});
});
