import { expect } from '@playwright/test';

import { parallelWorker as test } from '../fixtures/test.js';

test.describe('Toolbar', () => {
  test('Bold button', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    await editor.pressSequentially('Hello, world!');

    // Select "world" by using shift+arrow keys
    await editor.press('ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');

    const boldButton = app.locator('button[title="Bold"]');
    await boldButton.click();
    await expect(editor.locator('strong')).toHaveText('world');
    await boldButton.click();
    await expect(editor.locator('strong')).toHaveCount(0);

    await editor.press('Control+b');
    await expect(editor.locator('strong')).toHaveText('world');
    await editor.press('Control+b');
    await expect(editor.locator('strong')).toHaveCount(0);
  });

  test('Italic button', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    await editor.pressSequentially('Hello, world!');

    // Select "world" by using shift+arrow keys
    await editor.press('ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');

    const italicButton = app.locator('button[title="Italic"]');
    await italicButton.click();
    await expect(editor.locator('em')).toHaveText('world');
    await italicButton.click();
    await expect(editor.locator('em')).toHaveCount(0);

    await editor.press('Control+i');
    await expect(editor.locator('em')).toHaveText('world');
    await editor.press('Control+i');
    await expect(editor.locator('em')).toHaveCount(0);
  });

  test('Blockquote', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    await editor.pressSequentially('Hello, world!');

    // Move to the start of the sentence.
    await editor.press('Control+ArrowLeft');

    const quoteButton = app.locator('button[title="Quote"]');
    await quoteButton.click();
    await expect(editor.locator('blockquote')).toHaveText('Hello, world!');

    // Verify the dropdown shows "Quote" is selected
    const blockFormatSelect = app.locator('select[aria-label="Select block formatting"]');
    await expect(blockFormatSelect).toHaveValue('quote');
  });

  test('Undo and redo', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    await editor.pressSequentially('Hello, world!');

    // Select "Heading 1" from the block formatting dropdown
    const blockFormatSelect = app.locator('select[aria-label="Select block formatting"]');
    await blockFormatSelect.selectOption('h1');
    await expect(editor.locator('h1')).toHaveText('Hello, world!');

    // Click Undo and verify heading is removed
    const undoButton = app.locator('button[title="Undo"]');
    await undoButton.click();
    await expect(editor.locator('h1')).toHaveCount(0);
    await expect(blockFormatSelect).toHaveValue('paragraph');

    // Click Redo and verify heading is restored
    const redoButton = app.locator('button[title="Redo"]');
    await redoButton.click();
    await expect(editor.locator('h1')).toHaveText('Hello, world!');
  });

  test('Lists', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    await editor.pressSequentially('Gritty');

    const bulletedListButton = app.locator('button[title="Bulleted List"]');
    await bulletedListButton.click();

    await editor.press('Enter');
    await editor.pressSequentially('Swoop');
    await editor.press('Enter');
    await editor.pressSequentially('Phanatic');

    await expect(editor.locator('ul')).toHaveCount(1);
    await expect(editor.locator('ul li')).toHaveCount(3);
    await expect(editor.locator('ul li').nth(0)).toHaveText('Gritty');
    await expect(editor.locator('ul li').nth(1)).toHaveText('Swoop');
    await expect(editor.locator('ul li').nth(2)).toHaveText('Phanatic');

    // Change the list to numbered list.
    const numberedListButton = app.locator('button[title="Numbered List"]');
    await numberedListButton.click();
    await expect(editor.locator('ul')).toHaveCount(0);
    await expect(editor.locator('ol')).toHaveCount(1);
    await expect(editor.locator('ol li')).toHaveCount(3);
  });

  test('Clear formatting', async ({ conductor, page }) => {
    const app = await conductor.open();
    await conductor.initializeKeywordsAndCompetitorUrls(app);
    await app.getByRole('tab', { name: 'Content outline' }).click();
    await page.locator('.loading').waitFor({ state: 'detached' });

    const editor = app.locator('.text-editor__content[contenteditable="true"]');
    await editor.click();

    const blockFormatSelect = app.locator('select[aria-label="Select block formatting"]');

    // Add a heading.
    await blockFormatSelect.selectOption('h2');
    await editor.pressSequentially('Heading');
    await editor.press('Enter');

    // Add bold text.
    await editor.press('Control+b');
    await editor.pressSequentially('Bold text');
    await editor.press('Control+b');
    await editor.press('Enter');

    // Add italic text.
    await editor.press('Control+i');
    await editor.pressSequentially('Italic text');
    await editor.press('Control+i');
    await editor.press('Enter');

    // Add a blockquote.
    const quoteButton = app.locator('button[title="Quote"]');
    await quoteButton.click();
    await editor.pressSequentially('Quote text');
    await editor.press('Enter');
    await editor.press('Enter');

    // Add a list item.
    const bulletedListButton = app.locator('button[title="Bulleted List"]');
    await bulletedListButton.click();
    await editor.pressSequentially('List item');

    await expect(editor.locator('h2')).toHaveCount(1);
    await expect(editor.locator('strong')).toHaveCount(1);
    await expect(editor.locator('em')).toHaveCount(1);
    await expect(editor.locator('blockquote')).toHaveCount(1);
    await expect(editor.locator('li')).toHaveCount(1);

    // Remove formatting.
    await editor.press('Control+a');
    const removeFormattingButton = app.locator('button[title="Remove Formatting"]');
    await removeFormattingButton.click();

    await expect(editor.locator('h2')).toHaveCount(0);
    await expect(editor.locator('strong')).toHaveCount(0);
    await expect(editor.locator('em')).toHaveCount(0);
    await expect(editor.locator('blockquote')).toHaveCount(0);
    await expect(editor.locator('li')).toHaveCount(0);

    // Test partial clear formatting.
    await editor.press('Delete');
    await editor.click();
    await editor.pressSequentially('Hello, world!');
    await page.waitForTimeout(300);

    // Select "world" by using shift+arrow keys.
    await editor.press('ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');
    await editor.press('Shift+ArrowLeft');

    const italicButton = app.locator('button[title="Italic"]');
    await italicButton.click();
    await page.waitForTimeout(300);
    await expect(editor.locator('em')).toHaveText('world');
    await page.waitForTimeout(300);
  });
});
