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

const boundary = '#polymodel-viewer-boundary';
const canvas = '#polymodel-viewer-canvas';
const preview = '#polymodel-viewer-preview';
const assetPath = '/assets/models/body_f_chest-v4.stl';

async function expectViewerReady(page) {
  await expect(page.locator(canvas)).toHaveCount(1);
  await expect(page.locator(canvas)).toHaveAttribute('data-mounted', 'true');
  await expect(page.locator(preview)).toBeVisible();
}

test('viewer is reachable from browse and displays the committed STL asset', async ({ page }) => {
  await page.goto('/');
  await page.locator('header').getByRole('link', { name: 'Open viewer' }).click();

  await expect(page).toHaveURL(/\/viewer\/body-f-chest-v4$/);
  await expectViewerReady(page);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'body-f-chest-v4#1');
  await expect(page.locator(boundary)).toHaveAttribute('data-asset-path', assetPath);
  await expect(page.locator(boundary)).toContainText('Body F chest v4');
  await expect(page.locator(boundary)).toContainText(assetPath);
  await expect(page.locator(boundary)).toContainText('41051');
  await expect(page.locator(boundary)).toContainText('82122');
  await expect(page.locator(boundary)).toContainText('Viewer ready');
});

test('direct viewer routes select deterministic asset-backed models', async ({ page }) => {
  await page.goto('/viewer/body-f-chest-v4');
  await expectViewerReady(page);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'body-f-chest-v4#1');
  await expect(page.locator(boundary)).toHaveAttribute('data-asset-path', assetPath);
  await expect(page.locator(boundary)).toContainText('Body F chest v4');

  await page.goto('/viewer/body-f-chest-v4-detail');
  await expectViewerReady(page);
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'body-f-chest-v4-detail#2');
  await expect(page.locator(boundary)).toHaveAttribute('data-asset-path', assetPath);
  await expect(page.locator(boundary)).toContainText('Body F chest detail');
});

test('model switching keeps one canvas and updates renderer session metadata', async ({ page }) => {
  await page.goto('/viewer/body-f-chest-v4');
  await expectViewerReady(page);
  await expect(page.locator(canvas)).toHaveCount(1);

  await page.getByRole('button', { name: 'Body F chest detail' }).click();
  await expect(page.locator(canvas)).toHaveCount(1);
  await expect(page.locator(preview)).toBeVisible();
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'body-f-chest-v4-detail#2');
  await expect(page.locator(boundary)).toHaveAttribute('data-asset-path', assetPath);

  await page.getByRole('button', { name: 'Body F chest v4' }).click();
  await expect(page.locator(canvas)).toHaveCount(1);
  await expect(page.locator(preview)).toBeVisible();
  await expect(page.locator(boundary)).toHaveAttribute('data-session-label', 'body-f-chest-v4#1');
});

test('resize callback remains single after model transitions', async ({ page }) => {
  await page.goto('/viewer/body-f-chest-v4');
  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: 'Body F chest detail' }).click();

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