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-r7-project.zip',
);

test('R14.23.3 makes Visual block handles hover-first and keeps rich controls source-backed', async ({ page }) => {
  const workspaceName = `latex-r14-23-3-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  await page.getByLabel('Import Project ZIP').setInputFiles(fixture);
  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  await page.getByRole('button', { name: 'Visual' }).click();

  const visual = page.locator('.interactive-latex-visual-editor');
  await expect(visual).toBeVisible();

  // Learnitive-style: hovering the left edge is enough to surface +. No block click first.
  const paragraph = visual.locator('.interactive-visual-paragraph').first();
  await paragraph.hover({ position: { x: 2, y: 10 } });
  const handle = page.locator('[data-block-handle]');
  await expect(handle).toBeVisible();
  await expect(handle.locator('[data-add-block-button]')).toBeVisible();
  await handle.locator('[data-add-block-button]').click();
  await expect(page.getByText('BASIC', { exact: true })).toBeVisible();
  await expect(page.getByText('Equation', { exact: true })).toBeVisible();
  await expect(page.getByText('Display Math', { exact: true })).toHaveCount(0);
  await page.getByText('Table', { exact: true }).click();
  const visualTablePicker = page.getByTestId('latex-visual-table-picker-dialog');
  await expect(visualTablePicker).toBeVisible();
  const visualThreeByFour = visualTablePicker.locator('[data-table-grid-row="3"][data-table-grid-column="4"]');
  await visualThreeByFour.hover();
  await expect(visualTablePicker.getByText('3 × 4', { exact: true })).toBeVisible();
  await page.keyboard.press('Escape');

  // Figure metadata must sit above the image and expose placement controls.
  await visual.locator('.interactive-visual-figure').click();
  const figureDialog = page.getByRole('dialog');
  await expect(figureDialog).toHaveClass(/z-\[160\]/);
  await figureDialog.getByLabel('Placement').fill('H');
  await figureDialog.getByRole('button', { name: 'Apply' }).click();

  // Select a cell, then use the compact Learnitive-style structure menu relative to that cell.
  const firstCell = visual.locator('.interactive-visual-table td').first();
  await firstCell.click();
  await visual.locator('.interactive-visual-table-actions-summary').click();
  await page.getByRole('button', { name: 'Add row below', exact: true }).click();

  // Metadata stays intentionally small; row/column structure no longer lives in this dialog.
  await visual.locator('.interactive-visual-table-meta-button').click();
  const tableDialog = page.getByRole('dialog');
  await expect(tableDialog.getByLabel('Caption')).toBeVisible();
  await expect(tableDialog.getByLabel('Placement')).toBeVisible();
  await expect(tableDialog.getByLabel('Label')).toBeVisible();
  await expect(tableDialog.getByRole('button', { name: 'Add row below' })).toHaveCount(0);
  await tableDialog.getByRole('button', { name: 'Cancel' }).click();

  // Reference chips are editable and still offer explicit navigation to the target.
  await visual.locator('.interactive-visual-inline-reference').first().click();
  const referenceDialog = page.getByRole('dialog');
  await expect(referenceDialog.getByText('Edit reference')).toBeVisible();
  await expect(referenceDialog.getByRole('button', { name: /Go to current target/ })).toBeVisible();
  await page.keyboard.press('Escape');

  await page.getByRole('button', { name: 'Source' }).click();
  const source = page.getByLabel('LaTeX source editor');
  await expect(source).toContainText('\\begin{figure}[H]');
  await expect(source).toContainText('  &  \\\\');

  // The single MathLive entry exposes Inline + Equation only.
  await page.getByRole('button', { name: 'Equation editor' }).click();
  const mathDialog = page.getByTestId('mathlive-equation-editor');
  await expect(mathDialog.getByRole('button', { name: 'Inline' })).toBeVisible();
  await expect(mathDialog.getByRole('button', { name: 'Equation' })).toBeVisible();
  await expect(mathDialog.getByRole('button', { name: 'Display' })).toHaveCount(0);
});


test('BF3 freshly inserted Visual table focuses the canonical empty first-cell source anchor', async ({ page }) => {
  const workspaceName = `latex-bf3-empty-table-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  const source = page.getByLabel('LaTeX source editor');
  await source.fill('\\documentclass{article}\n\\begin{document}\nStart\n\\end{document}\n');
  await source.press(process.platform === 'darwin' ? 'Meta+s' : 'Control+s');
  await page.getByRole('button', { name: 'Visual' }).click();

  const visual = page.locator('.interactive-latex-visual-editor');
  const paragraph = visual.locator('.interactive-visual-paragraph').filter({ hasText: 'Start' }).first();
  await paragraph.hover({ position: { x: 2, y: 10 } });
  const handle = page.locator('[data-block-handle]');
  await handle.locator('[data-add-block-button]').click();
  await page.getByText('Table', { exact: true }).click();
  const picker = page.getByTestId('latex-visual-table-picker-dialog');
  await picker.locator('[data-table-grid-row="2"][data-table-grid-column="2"]').click();

  await page.keyboard.type('Alpha');
  const firstCell = visual.locator('.interactive-visual-table td').first();
  await expect(firstCell).toContainText('Alpha');
  await expect(visual.locator('[data-visual-synthetic-inline="true"]')).toHaveCount(0);

  const lastCell = visual.locator('.interactive-visual-table td').last();
  await lastCell.click();
  await page.keyboard.press('End');
  await page.keyboard.press('ArrowDown');
  await page.keyboard.type('After table.');
  await expect(
    visual.locator('.interactive-visual-paragraph').filter({ hasText: 'After table.' }),
  ).toBeVisible();

  await page.getByRole('button', { name: 'Source' }).click();
  await expect(source).toContainText('\\begin{tabular}{|l|l|}');
  await expect(source).toContainText('\\hline');
  await expect(source).toContainText('  Alpha &  \\\\');
  await expect(source).toContainText('After table.');
});
