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

const saveShortcut = process.platform === 'darwin' ? 'Meta+s' : 'Control+s';

async function createTextFile(page: Page, fileName: string, content: string) {
  const explorer = page.getByTestId('interactive-file-explorer');
  await explorer.getByRole('button', { name: 'New File' }).click();
  const dialog = page.getByRole('dialog', { name: 'Create Project File' });
  await dialog.getByLabel('File name').fill(fileName);
  await dialog.getByRole('button', { name: 'Create' }).click();
  const source = page.getByLabel('LaTeX source editor');
  await source.fill(content);
  await source.press(saveShortcut);
  await expect(page.getByText('Saved', { exact: true })).toBeVisible();
}

async function openCitationDialog(page: Page) {
  const toolbar = page.getByTestId('latex-plugin-toolbar');
  const direct = toolbar.locator('[data-toolbar-item="citation"]');
  if (await direct.count()) await direct.click();
  else {
    await toolbar.getByRole('button', { name: 'More editor commands' }).click();
    await page.locator('[data-toolbar-item="citation"]').click();
  }
  return page.getByRole('dialog', { name: 'References' });
}

test('R14.25.1 provides literature candidates, citation checking, shortlist decisions, DOI review and source-anchored manuscript research review', async ({ page }) => {
  const workspaceName = `research-r14-25-1-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });

  await createTextFile(page, 'refs.bib', [
    '@article{smith2024old,',
    '  title = {Browser Local Evidence},',
    '  author = {Smith, Ada},',
    '  year = {2024},',
    '  doi = {10.1000/duplicate}',
    '}',
    '@article{smith2024duplicate,',
    '  title = {Browser-Local Evidence Revised},',
    '  author = {Smith, Ada},',
    '  year = {2025},',
    '  doi = {10.1000/duplicate}',
    '}',
    '@article{researcher2025candidate,',
    '  title = {Browser Local DOI Candidate},',
    '  author = {Researcher, Ada},',
    '  year = {2025}',
    '}',
    '',
  ].join('\n'));

  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  const source = page.getByLabel('LaTeX source editor');
  await source.fill([
    '\\documentclass{article}',
    '\\begin{document}',
    'Our repeated experiments demonstrate that browser-local scientific editing improves reproducibility by twenty percent across independent trials, reduces accidental project divergence, and produces a measurable improvement in the consistency of the resulting manuscript workflow.',
    '',
    'A related result uses an old key \\cite{smith2024oldd}.',
    '',
    '\\begin{figure}',
    '\\centering',
    '\\rule{2cm}{1cm}',
    '\\end{figure}',
    '',
    '\\bibliography{refs}',
    '\\end{document}',
    '',
  ].join('\n'));
  await source.press(saveShortcut);
  await expect(page.getByText('Saved', { exact: true })).toBeVisible();

  await page.route('https://api.openalex.org/works**', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        meta: { count: 2 },
        results: [
          {
            id: 'https://openalex.org/W-SUPPORT',
            display_name: 'Browser Local Scientific Editing and Reproducibility',
            publication_year: 2026,
            doi: 'https://doi.org/10.1000/supporting',
            type: 'article',
            cited_by_count: 52,
            authorships: [{ author: { display_name: 'Ada Researcher' } }],
            primary_location: { source: { display_name: 'Journal of Local Research' } },
            open_access: { is_oa: true },
            abstract_inverted_index: {
              browser: [0], local: [1], scientific: [2], editing: [3], improves: [4], reproducibility: [5],
            },
          },
          {
            id: 'https://openalex.org/W-DOI',
            display_name: 'Browser Local DOI Candidate',
            publication_year: 2025,
            doi: 'https://doi.org/10.1000/browser-doi',
            type: 'article',
            cited_by_count: 3,
            authorships: [{ author: { display_name: 'Ada Researcher' } }],
            primary_location: { source: { display_name: 'Metadata Journal' } },
            open_access: { is_oa: false },
          },
        ],
      }),
    });
  });

  await page.route('https://api.crossref.org/works**', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        message: {
          'total-results': 2,
          items: [
            {
              title: ['Browser Local Scientific Editing and Reproducibility'],
              DOI: '10.1000/supporting',
              author: [{ given: 'Ada', family: 'Researcher' }],
              published: { 'date-parts': [[2026]] },
              type: 'journal-article',
              'is-referenced-by-count': 52,
              'container-title': ['Journal of Local Research'],
            },
            {
              title: ['Browser Local DOI Candidate'],
              DOI: '10.1000/browser-doi',
              author: [{ given: 'Ada', family: 'Researcher' }],
              published: { 'date-parts': [[2025]] },
              type: 'journal-article',
              'is-referenced-by-count': 3,
              'container-title': ['Metadata Journal'],
            },
          ],
        },
      }),
    });
  });

  // Keep the multi-provider search deterministic without depending on the
  // external Semantic Scholar service in CI.
  await page.route('https://api.semanticscholar.org/**', async (route) => {
    await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ total: 0, data: [] }) });
  });

  const dialog = await openCitationDialog(page);
  await dialog.getByRole('tab', { name: 'Suggested', exact: true }).click();
  await expect(dialog.getByTestId('reference-research-assistance')).toBeVisible();
  await expect(dialog.getByTestId('citation-checker')).toContainText('Multiple bibliography entries use DOI 10.1000/duplicate');
  await expect(dialog.getByTestId('citation-checker')).toContainText('may have been renamed to smith2024old');

  await dialog.getByPlaceholder('Paste a claim or describe the literature you need').fill('browser local scientific editing improves reproducibility');
  await dialog.getByRole('button', { name: 'Find papers' }).click();
  await expect(dialog).toContainText('Browser Local Scientific Editing and Reproducibility');
  await expect(dialog).toContainText(/candidate supporting source/i);
  await expect(dialog).toContainText(/not proof that a paper supports/i);

  const suggestion = dialog.locator('article').filter({ hasText: 'Browser Local Scientific Editing and Reproducibility' }).first();
  await suggestion.getByRole('button', { name: 'Save to shortlist' }).click();
  const shortlist = dialog.getByTestId('literature-shortlist');
  await expect(shortlist).toContainText('Browser Local Scientific Editing and Reproducibility');
  const shortlistItem = shortlist.locator('article').filter({ hasText: 'Browser Local Scientific Editing and Reproducibility' });
  await shortlistItem.getByRole('combobox').click();
  await page.getByRole('option', { name: 'Excluded', exact: true }).click();
  await shortlistItem.getByLabel('Reason / decision').fill('Outside the target experimental setting');

  await dialog.getByRole('button', { name: 'Check missing DOIs online' }).click();
  await expect(dialog).toContainText('researcher2025candidate → DOI 10.1000/browser-doi');
  await dialog.getByRole('button', { name: 'Add DOI' }).click();
  await expect(dialog).toContainText(/0 entries may be eligible for DOI lookup/);

  const persistedShortlist = await page.evaluate((name) => {
    return JSON.parse(localStorage.getItem(`learnitive:reference-shortlist:v2:${name}`) ?? '[]');
  }, workspaceName);
  expect(persistedShortlist[0]?.state).toBe('excluded');
  expect(persistedShortlist[0]?.reason).toBe('Outside the target experimental setting');

  await page.keyboard.press('Escape');
  await page.getByRole('link', { name: /^refs\.bib$/ }).click();
  await expect(page.getByLabel('LaTeX source editor')).toContainText('doi = {10.1000/browser-doi}');

  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  await page.getByRole('button', { name: 'Project Tools' }).click();
  const tools = page.getByTestId('interactive-project-tools-dialog');
  await tools.getByRole('button', { name: 'Research Review', exact: true }).click();
  await expect(tools.getByTestId('interactive-research-review')).toContainText('Potential citation gap');
  await expect(tools.getByTestId('interactive-research-review')).toContainText('Figure has no caption');
  await expect(tools.getByTestId('interactive-research-review')).toContainText('Figure has no label');
  await expect(tools.getByTestId('interactive-research-review')).toContainText(/never inserts citations, changes claims, or rewrites LaTeX automatically/i);
});
