import { test, expect } from '../../fixtures/multi-client';
import { openSettingsFromMenu } from '../../helpers/app-menu';
import { expectDashboardReady } from '../../helpers/dashboard';
import { RegisterPage } from '../../pages/register.page';

test.describe('ICE server settings', () => {
  test.describe.configure({ timeout: 120_000 });

  async function registerAndOpenNetworkSettings(page: import('@playwright/test').Page, suffix: string) {
    const register = new RegisterPage(page);

    await register.goto();
    await register.register(`user_${suffix}`, 'IceTestUser', 'TestPass123!');
    await expectDashboardReady(page);
    await openSettingsFromMenu(page);
    await expect(page.getByRole('button', { name: 'Network' })).toBeVisible({ timeout: 10_000 });
    await page.getByRole('button', { name: 'Network' }).click();
    await expect(page.getByTestId('ice-server-settings')).toBeVisible({ timeout: 10_000 });
  }

  test('allows adding, removing, and reordering ICE servers', async ({ createClient }) => {
    const client = await createClient();
    const { page } = client;
    const suffix = `ice_${Date.now()}`;

    await test.step('Register and open Network settings', async () => {
      await registerAndOpenNetworkSettings(page, suffix);
    });

    const iceSection = page.getByTestId('ice-server-settings');

    await test.step('Default STUN servers are listed', async () => {
      await expect(iceSection).toBeVisible({ timeout: 5_000 });
      const entries = page.getByTestId('ice-server-list').locator('[data-testid^="ice-entry-"]');

      await expect(entries.first()).toBeVisible({ timeout: 5_000 });
      const count = await entries.count();

      expect(count).toBeGreaterThanOrEqual(1);
    });

    await test.step('Add a STUN server', async () => {
      await page.getByTestId('ice-type-select').selectOption('stun');
      await page.getByTestId('ice-url-input').fill('stun:custom.example.com:3478');
      await page.getByTestId('ice-add-button').click();
      await expect(page.getByText('stun:custom.example.com:3478')).toBeVisible({ timeout: 5_000 });
    });

    await test.step('Add a TURN server with credentials', async () => {
      await page.getByTestId('ice-type-select').selectOption('turn');
      await page.getByTestId('ice-url-input').fill('turn:relay.example.com:443');
      await page.getByTestId('ice-username-input').fill('testuser');
      await page.getByTestId('ice-credential-input').fill('testpass');
      await page.getByTestId('ice-add-button').click();
      await expect(page.getByText('turn:relay.example.com:443')).toBeVisible({ timeout: 5_000 });
      await expect(page.getByText('User: testuser')).toBeVisible({ timeout: 5_000 });
    });

    await test.step('Remove first entry and verify count decreases', async () => {
      const entries = page.getByTestId('ice-server-list').locator('[data-testid^="ice-entry-"]');
      const countBefore = await entries.count();

      await entries.first().getByTitle('Remove')
        .click();

      await expect(entries).toHaveCount(countBefore - 1, { timeout: 5_000 });
    });

    await test.step('Reorder: move second entry up', async () => {
      const entries = page.getByTestId('ice-server-list').locator('[data-testid^="ice-entry-"]');
      const count = await entries.count();

      if (count >= 2) {
        const secondText = await entries.nth(1).locator('p')
          .first()
          .textContent();

        if (!secondText) {
          throw new Error('Expected ICE server entry text before reordering');
        }

        await entries.nth(1).getByTitle('Move up (higher priority)')
          .click();

        // Wait for the moved entry text to appear at position 0
        await expect(entries.first().locator('p')
          .first()).toHaveText(secondText, { timeout: 5_000 });
      }
    });

    await test.step('Restore defaults resets list', async () => {
      await page.getByTestId('ice-restore-defaults').click();
      await expect(page.getByText('turn:relay.example.com:443')).not.toBeVisible({ timeout: 3_000 });
      const entries = page.getByTestId('ice-server-list').locator('[data-testid^="ice-entry-"]');

      await expect(entries.first()).toBeVisible({ timeout: 5_000 });
    });

    await test.step('Settings persist after page reload', async () => {
      await page.getByTestId('ice-type-select').selectOption('stun');
      await page.getByTestId('ice-url-input').fill('stun:persist-test.example.com:3478');
      await page.getByTestId('ice-add-button').click();
      await expect(page.getByText('stun:persist-test.example.com:3478')).toBeVisible({ timeout: 5_000 });

      await page.reload({ waitUntil: 'domcontentloaded' });
      await openSettingsFromMenu(page);
      await expect(page.getByRole('button', { name: 'Network' })).toBeVisible({ timeout: 10_000 });
      await page.getByRole('button', { name: 'Network' }).click();
      await expect(page.getByText('stun:persist-test.example.com:3478')).toBeVisible({ timeout: 10_000 });
    });
  });

  test('validates TURN entries require credentials', async ({ createClient }) => {
    const client = await createClient();
    const { page } = client;
    const suffix = `iceval_${Date.now()}`;

    await test.step('Register and open Network settings', async () => {
      await registerAndOpenNetworkSettings(page, suffix);
    });

    await test.step('Adding TURN without credentials shows error', async () => {
      await page.getByTestId('ice-type-select').selectOption('turn');
      await page.getByTestId('ice-url-input').fill('turn:noncred.example.com:443');
      await page.getByTestId('ice-add-button').click();
      await expect(page.getByText('Username is required for TURN servers')).toBeVisible({ timeout: 5_000 });
    });
  });
});
