/**
 * O-series — Fase 2b.2 (offline-first)
 *
 * Uses Playwright's `context.setOffline(true)` to simulate a dropped
 * connection, then verifies that:
 *   (a) mutations still work locally (optimistic UI + enqueue)
 *   (b) a banner tells the user they're offline
 *   (c) going back online flushes the queue and the items persist server-side
 */
import { test, expect } from '@playwright/test';
import { USERS } from '../fixtures/users.js';
import { loginAs } from '../fixtures/login.js';

const SEED_LIST_PATH = '/lists/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb';
const ADD_ITEM_PLACEHOLDER = /add item|añadir producto/i;

test.describe('Offline queue + reconnect flush', () => {
	test('O-01: going offline shows the banner and optimistic adds stay visible', async ({
		page,
		context
	}) => {
		await loginAs(page, USERS.borja);
		await page.goto(SEED_LIST_PATH);
		await expect(page.getByPlaceholder(ADD_ITEM_PLACEHOLDER)).toBeVisible({ timeout: 15_000 });

		// Go offline. The SyncBanner subscribes to `navigator.onLine` via the
		// isOnline store and should render within a tick.
		await context.setOffline(true);
		await expect(page.getByTestId('sync-banner-offline')).toBeVisible({ timeout: 3_000 });

		const itemName = `O-01-${Date.now()}`;
		const input = page.getByPlaceholder(ADD_ITEM_PLACEHOLDER);
		await input.fill(itemName);
		await input.press('Enter');

		// Item renders locally even though the server call failed.
		await expect(page.getByText(itemName)).toBeVisible({ timeout: 3_000 });

		// Cleanup: bring the page back online so the next test starts fresh.
		await context.setOffline(false);
	});

	test('O-02: going back online flushes the queue to the server', async ({
		browser,
		context
	}) => {
		const page = await context.newPage();
		await loginAs(page, USERS.borja);
		await page.goto(SEED_LIST_PATH);
		await expect(page.getByPlaceholder(ADD_ITEM_PLACEHOLDER)).toBeVisible({ timeout: 15_000 });

		await context.setOffline(true);
		await expect(page.getByTestId('sync-banner-offline')).toBeVisible({ timeout: 3_000 });

		const itemName = `O-02-${Date.now()}`;
		const input = page.getByPlaceholder(ADD_ITEM_PLACEHOLDER);
		await input.fill(itemName);
		await input.press('Enter');
		await expect(page.getByText(itemName)).toBeVisible({ timeout: 3_000 });

		// Back online — the queue's 'online' listener flushes pending ops.
		await context.setOffline(false);
		await expect(page.getByTestId('sync-banner-offline')).not.toBeVisible({
			timeout: 5_000
		});

		// Verify server-side persistence with a FRESH independent context:
		// reload would use the same browser state; we want to prove the row
		// actually made it to the DB by loading the list from a new session.
		const verifyContext = await browser.newContext();
		const verifyPage = await verifyContext.newPage();
		await loginAs(verifyPage, USERS.ana);
		await verifyPage.goto(SEED_LIST_PATH);
		await expect(verifyPage.getByText(itemName)).toBeVisible({ timeout: 15_000 });
		await verifyContext.close();
	});
});
