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

const selectAll = process.platform === 'darwin' ? 'Meta+a' : 'Control+a';

test('BF4.4 keeps dual-mode comments outside canonical LaTeX source', async ({ page }) => {
  const workspaceName = `review-r14-27-0-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });

  const source = page.getByLabel('LaTeX source editor');
  const original = String.raw`\documentclass{article}
\begin{document}
Robust local research needs a supporting citation.
\end{document}`;
  await source.fill(original);

  // Source range comment: the canonical source selection is the review anchor.
  await source.press(selectAll);
  const manuscriptActions = page.getByTestId('paper-memory-manuscript-actions');
  await manuscriptActions.getByRole('button', { name: 'Comment', exact: true }).click();
  const dialog = page.getByRole('dialog', { name: 'Add comment' });
  await dialog.getByPlaceholder('Write a review comment…').fill('Please verify this claim before submission.');
  await dialog.getByRole('button', { name: 'Add comment' }).click();

  const sidebar = page.getByTestId('review-sidebar');
  await expect(sidebar).toBeVisible();
  await expect(sidebar).toContainText('Please verify this claim before submission.');
  await expect(page.locator('.cm-interactive-review-anchor')).toHaveCount(1);

  // Review metadata remains in Learnitive review storage and never pollutes canonical LaTeX.
  const sourceAfterComment = await source.inputValue();
  expect(sourceAfterComment).toBe(original);
  expect(sourceAfterComment).not.toContain('LEARNITIVE-REVIEW');
  expect(sourceAfterComment).not.toContain('<###');

  // The same canonical review object must be projected in Visual mode.
  await page.getByRole('button', { name: 'Visual', exact: true }).click();
  await expect(page.locator('.interactive-visual-comment-anchor')).toHaveCount(1);
  await page.locator('.interactive-visual-comment-anchor').first().click();
  await expect(sidebar).toContainText('Please verify this claim before submission.');
  await sidebar.getByRole('button', { name: 'Resolve', exact: true }).click();
  await expect(sidebar.getByText('resolved', { exact: true })).toBeVisible();

  // Resolved comments remain history and are visible in Source too.
  await page.getByRole('button', { name: 'Source', exact: true }).click();
  await expect(page.locator('.cm-interactive-review-resolved')).toHaveCount(1);
  await sidebar.getByRole('button', { name: 'Resolved', exact: true }).click();
  await expect(sidebar).toContainText('Please verify this claim before submission.');
  await sidebar.getByRole('button', { name: 'Reopen' }).click();

  // Point comments use the same repository but render as a CodeMirror bubble.
  await source.click();
  await page.getByRole('button', { name: /Comment/ }).filter({ has: page.locator('svg') }).last().click();
  const pointDialog = page.getByRole('dialog', { name: 'Add comment' });
  await pointDialog.getByPlaceholder('Write a review comment…').fill('Point comment at the current cursor.');
  await pointDialog.getByRole('button', { name: 'Add comment' }).click();
  await expect(page.locator('.cm-interactive-review-point')).toHaveCount(1);

  // Project comments have no source anchor and still live in the same sidebar.
  await sidebar.getByRole('button', { name: 'Project comment' }).click();
  const projectDialog = page.getByRole('dialog', { name: 'Project comment' });
  await projectDialog.getByPlaceholder('Write a review comment…').fill('Project-wide review note.');
  await projectDialog.getByRole('button', { name: 'Add comment' }).click();
  await expect(sidebar).toContainText('Project-wide review note.');

  // Local review storage survives reopening the app/workspace without changing the LaTeX source.
  await page.reload();
  await page.getByTestId('review-toggle').click();
  const reopened = page.getByTestId('review-sidebar');
  await reopened.getByRole('button', { name: 'All', exact: true }).click();
  await expect(reopened).toContainText('Please verify this claim before submission.');
  await expect(reopened).toContainText('Point comment at the current cursor.');
  await expect(reopened).toContainText('Project-wide review note.');
  const reopenedSource = await page.getByLabel('LaTeX source editor').inputValue();
  expect(reopenedSource).toBe(original);
  expect(reopenedSource).not.toContain('LEARNITIVE-REVIEW');
  expect(reopenedSource).not.toContain('<###');
});

test('BF4.1 maps a Visual comment decoration through native Learnitive typing', async ({ page }) => {
  const workspaceName = `review-bf41-visual-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });
  const source = page.getByLabel('LaTeX source editor');
  await source.fill(String.raw`\documentclass{article}
\begin{document}
Alpha target text.
\end{document}`);

  await page.getByRole('button', { name: 'Visual', exact: true }).click();
  const paragraph = page
    .locator('.interactive-latex-visual-editor .interactive-visual-paragraph')
    .filter({ hasText: 'Alpha target text.' })
    .first();
  await paragraph.click();
  await page.keyboard.press('Home');
  for (let index = 0; index < 'Alpha'.length; index += 1) {
    await page.keyboard.press('Shift+ArrowRight');
  }

  const manuscriptActions = page.getByTestId('paper-memory-manuscript-actions');
  await manuscriptActions.getByRole('button', { name: 'Comment', exact: true }).click();
  const dialog = page.getByRole('dialog', { name: 'Add comment' });
  await dialog.getByPlaceholder('Write a review comment…').fill('Keep this anchor on Alpha.');
  await dialog.getByRole('button', { name: 'Add comment' }).click();

  const highlight = page.locator('.interactive-visual-comment-anchor').first();
  await expect(highlight).toHaveText('Alpha');
  await paragraph.click();
  await page.keyboard.press('Home');
  await page.keyboard.type('Intro ');
  await expect(paragraph).toContainText('Intro Alpha target text.');
  await expect(highlight).toHaveText('Alpha');

  await highlight.click();
  const sidebar = page.getByTestId('review-sidebar');
  await expect(sidebar).toContainText('Keep this anchor on Alpha.');
  await sidebar.getByRole('button', { name: 'Resolve', exact: true }).click();
  await expect(page.locator('.interactive-visual-comment-anchor')).toHaveCount(0);
});
