import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { expect, test } from '@playwright/test';
import { createBrowserWorkspace } from './common';

const fixture = path.resolve(
  path.dirname(fileURLToPath(import.meta.url)),
  '../fixtures/interactive-source-project.zip',
);

test('browser LaTeX compile produces PDF and preserves last good output after an error', async ({
  page,
}) => {
  const workspaceName = `latex-compile-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  await page.getByRole('link', { name: 'Home', exact: true }).click();
  await page.getByLabel('Import Project ZIP').setInputFiles(fixture);

  const pdfPreview = page.getByTestId('interactive-pdf-preview');
  await page.getByRole('button', { name: 'Compile', exact: true }).click();
  await expect(pdfPreview.locator('canvas')).toBeVisible({ timeout: 120_000 });
  await expect(pdfPreview.getByRole('button', { name: 'Download compiled PDF' })).toBeVisible();

  await expect(pdfPreview).toBeVisible();
  const pdfCanvas = pdfPreview.locator('canvas');
  await expect(pdfCanvas).toBeVisible({ timeout: 30_000 });
  await expect(pdfPreview.getByText('SyncTeX ready', { exact: true })).toBeVisible();

  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  const source = page.getByLabel('LaTeX source editor');
  await source.click();
  await source.press(process.platform === 'darwin' ? 'Meta+Home' : 'Control+Home');
  await source.press('ArrowDown');
  await source.press('ArrowDown');
  await source.press('ArrowDown');
  await expect(page.getByTestId('latex-cursor-location')).toContainText('Ln 4');
  await page.getByLabel('Locate source in PDF').click();

  const sourceHighlight = page.getByTestId('synctex-source-highlight').first();
  await expect(sourceHighlight).toBeVisible();
  await page.getByLabel('PDF follows source cursor').uncheck();

  await source.press(process.platform === 'darwin' ? 'Meta+Home' : 'Control+Home');
  await expect(page.getByTestId('latex-cursor-location')).toContainText('Ln 1');
  const textLayer = pdfPreview.getByTestId('pdf-text-layer');
  const sourceFollowsPdf = page.getByLabel('Source follows PDF');
  if (!(await sourceFollowsPdf.isChecked())) await sourceFollowsPdf.check();
  const textLayerBox = await textLayer.boundingBox();
  const highlightBox = await sourceHighlight.boundingBox();
  if (!textLayerBox || !highlightBox) {
    throw new Error('Expected rendered PDF text layer and SyncTeX highlight bounds');
  }
  await textLayer.dblclick({
    modifiers: ['Alt'],
    position: {
      x: highlightBox.x - textLayerBox.x + highlightBox.width / 2,
      y: highlightBox.y - textLayerBox.y + highlightBox.height / 2,
    },
  });
  await expect(page.getByTestId('latex-cursor-location')).toContainText('Ln 4');

  await source.fill(
    [
      '\\documentclass{article}',
      '\\begin{document}',
      '\\definitelyUndefinedLearnitiveCommand',
      '\\end{document}',
      '',
    ].join('\n'),
  );
  await source.press(process.platform === 'darwin' ? 'Meta+s' : 'Control+s');

  await page.getByRole('button', { name: 'Compile', exact: true }).click();
  const logPane = pdfPreview.getByTestId('interactive-compile-log');
  await expect(logPane).toBeVisible({ timeout: 120_000 });
  await expect(logPane).toContainText(/Undefined control sequence/i);
  await pdfPreview.getByTestId('interactive-output-tabs').getByRole('button', { name: 'PDF' }).click();
  await expect(pdfPreview.locator('canvas')).toBeVisible();
});
