import {
  type Page,
  type Locator,
  expect
} from '@playwright/test';

export class ServerSearchPage {
  readonly searchInput: Locator;
  readonly createServerButton: Locator;
  readonly railDashboardButton: Locator;
  readonly settingsButton: Locator;

  // Create server page
  readonly serverNameInput: Locator;
  readonly serverDescriptionInput: Locator;
  readonly serverTopicInput: Locator;
  readonly signalEndpointSelect: Locator;
  readonly advancedSettingsToggle: Locator;
  readonly privateCheckbox: Locator;
  readonly serverPasswordInput: Locator;
  readonly createSubmitButton: Locator;
  readonly cancelButton: Locator;

  constructor(private page: Page) {
    // Server discovery lives on /servers via <app-server-browser>.
    this.searchInput = page.getByPlaceholder('Search servers...');
    this.railDashboardButton = page.locator('button[title="Dashboard"]');
    // Dashboard "Create Server" entry point.
    this.createServerButton = page.getByRole('link', { name: 'Create Server' }).first();
    this.settingsButton = page.locator('button[title="Settings"]');

    // Create-server page elements.
    this.serverNameInput = page.locator('#create-server-name');
    this.serverDescriptionInput = page.locator('#create-server-description');
    this.serverTopicInput = page.locator('#create-server-topic');
    this.signalEndpointSelect = page.locator('#create-server-signal-endpoint');
    this.advancedSettingsToggle = page.getByRole('button', { name: 'Advanced settings' });
    this.privateCheckbox = page.locator('#create-server-private');
    this.serverPasswordInput = page.locator('#create-server-password');
    this.createSubmitButton = page.locator('#create-server-submit');
    this.cancelButton = page.locator('#create-server-cancel');
  }

  async goto() {
    await this.page.goto('/servers');
  }

  async createServer(name: string, options?: { description?: string; topic?: string; sourceId?: string }) {
    await this.page.goto('/create-server', { waitUntil: 'domcontentloaded' });

    await expect(this.serverNameInput).toBeVisible({ timeout: 10_000 });
    await this.serverNameInput.fill(name);

    if (options?.description) {
      await this.serverDescriptionInput.fill(options.description);
    }

    if (options?.topic || options?.sourceId) {
      if (!await this.serverTopicInput.isVisible()) {
        await this.advancedSettingsToggle.click();
      }

      await expect(this.serverTopicInput).toBeVisible({ timeout: 10_000 });

      if (options?.topic) {
        await this.serverTopicInput.fill(options.topic);
      }

      if (options?.sourceId) {
        await this.signalEndpointSelect.selectOption(options.sourceId);
      }
    }

    await this.createSubmitButton.click();
  }

  async joinSavedRoom(name: string) {
    await this.page.getByRole('button', { name }).click();
  }

  async joinServerFromSearch(name: string, options: { acceptPluginDownloads?: boolean } = {}) {
    await this.page.goto('/servers', { waitUntil: 'domcontentloaded' });
    await expect(this.searchInput).toBeVisible({ timeout: 15_000 });
    await this.searchInput.fill(name);

    const serverCard = this.page.locator('div[title]', { hasText: name }).first();

    await expect(serverCard).toBeVisible({ timeout: 15_000 });
    await serverCard.dblclick();

    if (options.acceptPluginDownloads) {
      const pluginConsentDialog = this.page.getByRole('dialog', { name: /uses plugins/ });

      await expect(pluginConsentDialog).toBeVisible({ timeout: 20_000 });
      await pluginConsentDialog.getByRole('button', { name: 'Accept and join' }).click();
    }
  }
}
