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.0 searches scholarly providers, deduplicates existing works and adds/cites through the project bibliography', async ({ page }) => {
  const workspaceName = `references-r14-25-0-${Date.now()}`;
  await createBrowserWorkspace(page, { workspaceName });

  await createTextFile(page, 'refs.bib', [
    '@article{existing2025paper,',
    '  title = {Existing Evidence},',
    '  author = {Researcher, Ada},',
    '  year = {2025},',
    '  doi = {10.1000/existing}',
    '}',
    '',
  ].join('\n'));

  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  const source = page.getByLabel('LaTeX source editor');
  await source.fill([
    '\\documentclass{article}',
    '\\begin{document}',
    'Evidence goes here: ',
    '\\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-EXISTING',
            display_name: 'Existing Evidence (provider title variant)',
            publication_year: 2025,
            doi: 'https://doi.org/10.1000/existing',
            type: 'article',
            cited_by_count: 12,
            authorships: [{ author: { display_name: 'Ada Researcher' } }],
            primary_location: { source: { display_name: 'Journal A' } },
            open_access: { is_oa: true },
          },
          {
            id: 'https://openalex.org/W-NEW',
            display_name: 'New Evidence for Browser Local Research',
            publication_year: 2026,
            doi: 'https://doi.org/10.1000/new-evidence',
            type: 'article',
            cited_by_count: 21,
            authorships: [{ author: { display_name: 'Ada Researcher' } }],
            primary_location: { source: { display_name: 'Journal B' } },
            open_access: { is_oa: true },
          },
        ],
      }),
    });
  });

  const dialog = await openCitationDialog(page);
  await expect(dialog).toBeVisible();
  for (const tab of ['Search', 'Suggested', 'My Zotero', 'Local bibliography']) {
    await expect(dialog.getByRole('tab', { name: tab, exact: true })).toBeVisible();
  }

  await dialog.getByRole('tab', { name: 'Search', exact: true }).click();
  await dialog.getByRole('combobox').filter({ hasText: 'All providers' }).click().catch(() => undefined);
  // Select OpenAlex deterministically; the provider select is the first trigger
  // in the Search tab after the query field.
  const providerSelect = dialog.locator('button[role="combobox"]').first();
  await providerSelect.click();
  await page.getByRole('option', { name: 'OpenAlex', exact: true }).click();
  await dialog.getByPlaceholder('Search papers by title, author, DOI or topic').fill('browser local research');
  await dialog.getByRole('button', { name: 'Search', exact: true }).last().click();

  await expect(dialog).toContainText('Existing Evidence (provider title variant)');
  await expect(dialog).toContainText('Already in bibliography · existing2025paper');
  await expect(dialog).toContainText('New Evidence for Browser Local Research');
  await expect(dialog).toContainText('21 citations');

  const newResult = dialog.locator('article').filter({ hasText: 'New Evidence for Browser Local Research' });
  await newResult.getByRole('button', { name: 'Add & Cite' }).click();
  await expect(dialog).toBeHidden();
  await expect(source).toContainText('\\cite{researcher2026new}');

  await page.getByRole('link', { name: /^refs\.bib$/ }).click();
  const bibSource = page.getByLabel('LaTeX source editor');
  await expect(bibSource).toContainText('@article{researcher2026new,');
  await expect(bibSource).toContainText('doi = {10.1000/new-evidence}');

  // Provider credentials/settings remain browser-only and the UI makes the
  // external-network boundary explicit.
  await page.getByRole('link', { name: /^main\.tex$/ }).click();
  const reopened = await openCitationDialog(page);
  await reopened.getByRole('button', { name: 'Provider settings' }).click();
  await expect(reopened.getByText(/stored only in this browser/i)).toBeVisible();
  await expect(reopened.getByText(/does not upload your manuscript/i)).toBeVisible();
});
