import { test, expect } from '@playwright/test';
import { login } from './helpers/auth';

/**
 * These tests run WITHOUT the stored session so they can test the login flow itself.
 * Playwright's storageState is only applied for the 'chromium' project, which depends
 * on the 'setup' project. These tests use a fresh context via test.use({ storageState: undefined }).
 */
test.use({ storageState: { cookies: [], origins: [] } });

test.describe('Authentication', () => {
	test('login page renders correctly', async ({ page }) => {
		await page.goto('/login');
		await expect(page.getByLabel('Benutzername')).toBeVisible();
		await expect(page.getByLabel('Passwort')).toBeVisible();
		await expect(page.getByRole('button', { name: 'Anmelden' })).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/login-page.png' });
	});

	test('redirects unauthenticated users to /login', async ({ page }) => {
		await page.goto('/');
		await expect(page).toHaveURL(/\/login/);
		await page.screenshot({ path: 'test-results/e2e/auth-redirect.png' });
	});

	test('protected routes redirect to /login without session', async ({ page }) => {
		for (const url of ['/documents/new', '/persons', '/briefwechsel']) {
			await page.goto(url);
			await expect(page).toHaveURL(/\/login/);
		}
	});

	test('shows an error for wrong credentials', async ({ page }) => {
		await page.goto('/login');
		await page.getByLabel('Benutzername').fill('nichtexistent');
		await page.getByLabel('Passwort').fill('falschespasswort');
		await page.getByRole('button', { name: 'Anmelden' }).click();
		// Stays on login, shows error
		await expect(page).toHaveURL(/\/login/);
		await expect(page.locator('.text-red-600')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/login-error.png' });
	});

	test('login with valid credentials redirects to home', async ({ page }) => {
		await login(page);
		await expect(page).toHaveURL('/');
		await expect(page.getByPlaceholder('Suche in Titel, Inhalt, Ort...')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/login-success.png' });
	});

	test('login establishes a session that authenticates API calls', async ({ page }) => {
		// Guards against regressions where the session cookie is set but broken.
		// The profile page calls /api/users/me server-side — if auth works end-to-end,
		// it loads without redirecting to /login.
		await login(page);
		await page.goto('/profile');
		await expect(page).toHaveURL('/profile');
		await expect(page.getByRole('heading', { name: /Mein Profil/i })).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/auth-session-valid.png' });
	});

	test('logout clears the session and redirects to /login', async ({ page }) => {
		await login(page);
		// Wait for hydration before interacting with the nav — onclick handlers are
		// only wired up after SvelteKit finishes hydrating the page client-side.
		await page.waitForSelector('[data-hydrated]');
		// Logout is inside the user avatar dropdown — open it first.
		// Wait for the dropdown button to be visible before clicking Abmelden,
		// since the {#if userMenuOpen} block renders asynchronously in Svelte.
		await page.locator('button[aria-haspopup="true"]').click();
		await expect(page.getByRole('button', { name: 'Abmelden' })).toBeVisible();
		await page.getByRole('button', { name: 'Abmelden' }).click();
		await expect(page).toHaveURL(/\/login/);
		// Confirm session is gone: navigating to / redirects back
		await page.goto('/');
		await expect(page).toHaveURL(/\/login/);
		await page.screenshot({ path: 'test-results/e2e/logout.png' });
	});
});
