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

/**
 * Password-reset E2E tests.
 *
 * These tests run WITHOUT a stored session because they test unauthenticated flows.
 *
 * They rely on the "e2e" Spring profile being active in CI (see playwright.config.ts /
 * docker-compose.e2e.yml).  The profile exposes GET /api/auth/reset-token-for-test?email=
 * so we can retrieve the generated token without a real mail server.
 */
test.use({ storageState: { cookies: [], origins: [] } });

// The backend is accessible directly for E2E helper calls (no SvelteKit proxy needed).
const BACKEND_URL = process.env.E2E_BACKEND_URL ?? 'http://localhost:8080';

async function getResetToken(email: string): Promise<string> {
	const res = await fetch(
		`${BACKEND_URL}/api/auth/reset-token-for-test?email=${encodeURIComponent(email)}`
	);
	if (!res.ok) throw new Error(`Could not retrieve reset token for ${email}: ${res.status}`);
	return res.text();
}

test.describe('Password reset', () => {
	test('forgot-password page is accessible without login', async ({ page }) => {
		await page.goto('/forgot-password');
		await expect(page).toHaveURL('/forgot-password');
		await expect(page.getByRole('heading', { name: /Passwort vergessen/i })).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/password-reset-form.png' });
	});

	test('forgot-password shows success banner for any email (prevents user enumeration)', async ({
		page
	}) => {
		await page.goto('/forgot-password');
		await page.getByLabel(/E-Mail/i).fill('nonexistent@example.com');
		await page.getByRole('button', { name: /Link anfordern/i }).click();
		// Always shows success — never reveals whether the email exists
		await expect(page.locator('.bg-green-50')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/password-reset-success-banner.png' });
	});

	test('full password reset flow', async ({ page }) => {
		// Uses a dedicated low-privilege test account so the admin account is never touched.
		const testEmail = 'reset@familyarchive.local';
		const originalPassword = 'reset123';
		const newPassword = 'NewP@ssw0rd_E2E!';

		// 1. Request reset
		await page.goto('/forgot-password');
		await page.getByLabel(/E-Mail/i).fill(testEmail);
		await page.getByRole('button', { name: /Link anfordern/i }).click();
		await expect(page.locator('.bg-green-50')).toBeVisible();

		// 2. Fetch the token via the test helper endpoint
		const token = await getResetToken(testEmail);
		expect(token.length).toBeGreaterThan(0);

		// 3. Open the reset-password page with the token
		await page.goto(`/reset-password?token=${token}`);
		await expect(page.getByRole('heading', { name: /Neues Passwort/i })).toBeVisible();
		await page.getByLabel(/^Neues Passwort$/i).fill(newPassword);
		await page.getByLabel(/Passwort bestätigen/i).fill(newPassword);
		await page.getByRole('button', { name: /Passwort speichern/i }).click();

		// 4. Success banner — then navigate to login
		await expect(page.locator('.bg-green-50')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/password-reset-changed.png' });
		await page.getByRole('link', { name: /Zurück zum Login/i }).click();

		// 5. Log in with new password
		await expect(page).toHaveURL(/\/login/);
		await page.getByLabel('Benutzername').fill(testEmail);
		await page.getByLabel('Passwort').fill(newPassword);
		await page.getByRole('button', { name: 'Anmelden' }).click();
		await expect(page).toHaveURL('/');

		// 6. Restore original password via profile page
		await page.goto('/profile');
		await page.locator('input[name="currentPassword"]').fill(newPassword);
		await page.locator('input[name="newPassword"]').fill(originalPassword);
		await page.locator('input[name="confirmPassword"]').fill(originalPassword);
		await page.getByTestId('submit-password').click();
		// After changing password, auth_token is stale → redirect to login
		await expect(page).toHaveURL(/\/login/);

		// 7. Log back in with original password to confirm restore worked
		await page.getByLabel('Benutzername').fill(testEmail);
		await page.getByLabel('Passwort').fill(originalPassword);
		await page.getByRole('button', { name: 'Anmelden' }).click();
		await expect(page).toHaveURL('/');
		await page.screenshot({ path: 'test-results/e2e/password-reset-restored.png' });
	});

	test('reset-password page shows error for invalid token', async ({ page }) => {
		await page.goto('/reset-password?token=invalidtoken000');
		await page.getByLabel(/^Neues Passwort$/i).fill('somepassword');
		await page.getByLabel(/Passwort bestätigen/i).fill('somepassword');
		await page.getByRole('button', { name: /Passwort speichern/i }).click();
		await expect(page.locator('.text-red-600')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/password-reset-invalid-token.png' });
	});

	test('reset-password page shows mismatch error when passwords differ', async ({ page }) => {
		await page.goto('/reset-password?token=anytoken');
		await page.getByLabel(/^Neues Passwort$/i).fill('password1');
		await page.getByLabel(/Passwort bestätigen/i).fill('password2');
		await page.getByRole('button', { name: /Passwort speichern/i }).click();
		await expect(page.locator('.text-red-600')).toBeVisible();
		await page.screenshot({ path: 'test-results/e2e/password-reset-mismatch.png' });
	});
});
