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('direct .tex editor deep link survives a full reload', async ({ page }) => {
  const workspaceName = `latex-deep-link-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  await page.getByRole('link', { name: 'Home', exact: true }).click();
  await page.getByLabel('Import Project ZIP').setInputFiles(fixture);

  const route = `/ws#route=editor&wsPath=${encodeURIComponent(`${workspaceName}:main.tex`)}`;
  await page.goto(route, { waitUntil: 'domcontentloaded' });
  await expect(page.getByLabel('LaTeX source editor')).toBeVisible();
  await expect(page.getByRole('heading', { name: 'Page Not Found' })).toHaveCount(0);

  await page.reload({ waitUntil: 'domcontentloaded' });
  await expect(page).toHaveURL(new RegExp(`ws#route=editor&wsPath=${encodeURIComponent(`${workspaceName}:main.tex`)}$`));
  await expect(page.getByLabel('LaTeX source editor')).toBeVisible();
  await expect(page.getByRole('heading', { name: 'Page Not Found' })).toHaveCount(0);
});

test('LaTeX source files edit, autosave, reload, and insert project images', async ({
  page,
}) => {
  const workspaceName = `latex-source-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });

  await page.getByRole('link', { name: 'Home', exact: true }).click();
  await page.getByLabel('Import Project ZIP').setInputFiles(fixture);
  await expect(page.getByRole('link', { name: /^main\.tex$/ })).toBeVisible();
  await page.getByRole('link', { name: /^main\.tex$/ }).click();

  const source = page.getByLabel('LaTeX source editor');
  await expect(source).toBeVisible();
  await expect(source).toContainText('Hello Learnitive.');

  const edited = [
    '\\documentclass{article}',
    '\\usepackage{graphicx}',
    '\\begin{document}',
    'Edited in the Learnitive source editor.',
    '\\end{document}',
    '',
  ].join('\n');
  await source.fill(edited);
  await source.press(process.platform === 'darwin' ? 'Meta+z' : 'Control+z');
  await expect(source).toContainText('Hello Learnitive.');
  await source.press(
    process.platform === 'darwin' ? 'Shift+Meta+z' : 'Control+y',
  );
  await expect(source).toContainText('Edited in the Learnitive source editor.');
  await source.press(process.platform === 'darwin' ? 'Meta+s' : 'Control+s');
  await expect(page.getByText('Saved', { exact: true })).toBeVisible();

  await page.reload({ waitUntil: 'domcontentloaded' });
  const reloaded = page.getByLabel('LaTeX source editor');
  await expect(reloaded).toContainText('Edited in the Learnitive source editor.');

  await reloaded.click();
  await reloaded.press(
    process.platform === 'darwin' ? 'Meta+ArrowDown' : 'Control+End',
  );
  await page
    .locator('input[type="file"][aria-label="Insert image"]')
    .setInputFiles({
      name: 'System Diagram.png',
      mimeType: 'image/png',
      buffer: Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
    });

  await expect(reloaded).toContainText('\\begin{figure}[htbp]');
  await expect(reloaded).toContainText(
    '\\includegraphics[width=0.80\\linewidth]{figures/System-Diagram.png}',
  );
  await expect(page.getByText(/Inserted System-Diagram\.png/)).toBeVisible();
});

test('MathLive edits existing math losslessly and inserts display equations', async ({
  page,
}) => {
  const workspaceName = `mathlive-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  await page.getByRole('link', { name: 'Home', exact: true }).click();
  await page.getByLabel('Import Project ZIP').setInputFiles(fixture);
  await page.getByRole('link', { name: /^main\.tex$/ }).click();

  const source = page.getByLabel('LaTeX source editor');
  const mathSource = [
    '\\documentclass{article}',
    '\\begin{document}',
    'Energy is $E = mc^2$ in this equation.',
    '\\end{document}',
    '',
  ].join('\n');
  await source.fill(mathSource);
  await source.evaluate((element) => {
    const view = (element as HTMLElement).closest('.cm-editor');
    if (!view) throw new Error('CodeMirror editor not found');
  });

  await source.click();
  await source.press(process.platform === 'darwin' ? 'Meta+f' : 'Control+f');
  await page.keyboard.type('mc^2');
  await page.keyboard.press('Escape');
  await page.keyboard.press('ArrowRight');

  const preview = page.getByTitle('Edit equation');
  await expect(preview).toBeVisible();
  await preview.click();
  const editor = page.getByTestId('mathlive-equation-editor');
  await expect(editor).toBeVisible();
  await editor.locator('math-field').evaluate((element) => {
    const field = element as HTMLElement & { value: string };
    field.value = 'E = \\gamma mc^2';
    field.dispatchEvent(new Event('input', { bubbles: true }));
  });
  await editor.getByRole('button', { name: 'Apply' }).click();
  await expect(source).toContainText('$E = \\gamma mc^2$');

  await page.getByRole('button', { name: 'Equation' }).click();
  const insertEditor = page.getByTestId('mathlive-equation-editor');
  await insertEditor.locator('math-field').evaluate((element) => {
    const field = element as HTMLElement & { value: string };
    field.value = '\\frac{a}{b}';
    field.dispatchEvent(new Event('input', { bubbles: true }));
  });
  await insertEditor.getByRole('button', { name: 'Apply' }).click();
  await expect(source).toContainText('\\[');
  await expect(source).toContainText('\\frac{a}{b}');

  await source.press(process.platform === 'darwin' ? 'Meta+z' : 'Control+z');
  await expect(source).not.toContainText('\\frac{a}{b}');
});
