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

const boundary = '#polymodel-viewer-boundary';
const canvas = '#polymodel-viewer-canvas';
async function expectViewerReady(page) { await expect(page.locator(canvas)).toHaveCount(1); await expect(page.locator(canvas)).toHaveAttribute('data-mounted', 'true'); }
test('viewer is reachable from browse and owns one mounted canvas', async ({ page }) => {
  await page.goto('/');
  await page.getByRole('link', { name: 'Open canvas-isolated viewer demo' }).click();

  await expect(page).toHaveURL(/\/viewer\/calibration-cube$/);
  await expectViewerReady(page);
  await expect(page.locator(canvas)).toHaveAttribute('data-mounted', 'true');
  await expect(page.locator(boundary)).toContainText('Calibration cube');
  await expect(page.locator(boundary)).toContainText('Stub renderer ready');
});

test('direct viewer routes select deterministic demo models', async ({ page }) => {
  await page.goto('/viewer/calibration-cube');
  await expectViewerReady(page);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'calibration-cube#1');
  await expect(page.locator(boundary)).toContainText('Calibration cube');

  await page.goto('/viewer/benchy-hull');
  await expectViewerReady(page);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'benchy-hull#2');
  await expect(page.locator(boundary)).toContainText('Benchy hull stub');
});

test('viewer state controls show loading and product-facing errors', async ({ page }) => {
  await page.goto('/viewer/calibration-cube');
  await expectViewerReady(page);
  await page.getByRole('button', { name: 'No mesh' }).click(); await expect(page.locator(boundary)).toContainText('No mesh selected'); await expect(page.locator(boundary)).not.toContainText('Vertices'); await page.getByRole('button', { name: 'Loading' }).click();
  await expect(page.locator(boundary)).toContainText('Loading mesh');
  await expect(page.locator(boundary)).not.toContainText('Vertices');

  await page.getByRole('button', { name: 'Unsupported' }).click();
  await expect(page.locator(boundary)).toContainText('This model format is not supported yet.');
  await expect(page.locator(boundary)).not.toContainText('Vertices');

  await page.getByRole('button', { name: 'Too large' }).click();
  await expect(page.locator(boundary)).toContainText('This model is too large for the browser viewer.'); await expect(page.locator(boundary)).not.toContainText('Vertices');

  await page.getByRole('button', { name: 'Renderer error' }).click();
  await expect(page.locator(boundary)).toContainText('The viewer could not start on this canvas.');
  await expect(page.locator(boundary)).toHaveAttribute('data-session-wanted', 'false'); await expect(page.locator(boundary)).not.toContainText('Vertices');
});

test('model switching keeps one canvas and updates the session', async ({ page }) => {
  await page.goto('/viewer/calibration-cube');
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'calibration-cube#1');
  await expectViewerReady(page);
  await page.getByRole('button', { name: 'Benchy hull stub' }).click();
  await expect(page.locator(canvas)).toHaveCount(1);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'benchy-hull#2');
  await expect(page.locator(boundary)).toContainText('Benchy hull stub');

  await page.getByRole('button', { name: 'Calibration cube' }).click();
  await expect(page.locator(canvas)).toHaveCount(1);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'calibration-cube#1');
});

test('resize callback remains single after state and model transitions', async ({ page }) => {
  await page.goto('/viewer/calibration-cube');
  const currentResizeCount = async () => Number(await page.locator(boundary).getAttribute('data-resize-count'));
  await expectViewerReady(page);
  const before = await currentResizeCount();
  await page.setViewportSize({ width: 1100, height: 760 });
  await expect.poll(currentResizeCount).toBe(before + 1);

  await page.getByRole('button', { name: 'Renderer error' }).click();
  await page.getByRole('button', { name: 'Ready' }).click();
  await page.getByRole('button', { name: 'Benchy hull stub' }).click();

  const afterTransitions = await currentResizeCount();
  await page.setViewportSize({ width: 1000, height: 700 });
  await expect.poll(currentResizeCount).toBe(afterTransitions + 1);
});
