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

export class ServerSearchPage {
  readonly searchInput: Locator;
  readonly createServerButton: Locator;
  readonly railCreateServerButton: Locator;
  readonly searchCreateServerButton: Locator;
  readonly settingsButton: Locator;

  // Create server dialog
  readonly serverNameInput: Locator;
  readonly serverDescriptionInput: Locator;
  readonly serverTopicInput: Locator;
  readonly signalEndpointSelect: Locator;
  readonly privateCheckbox: Locator;
  readonly serverPasswordInput: Locator;
  readonly dialogCreateButton: Locator;
  readonly dialogCancelButton: Locator;

  constructor(private page: Page) {
    this.searchInput = page.getByPlaceholder('Search servers and users...');
    this.railCreateServerButton = page.locator('button[title="Create Server"]');
    this.searchCreateServerButton = page.getByRole('button', { name: 'Create New Server' });
    this.createServerButton = this.searchCreateServerButton;
    this.settingsButton = page.locator('button[title="Settings"]');

    // Create dialog 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.privateCheckbox = page.locator('#private');
    this.serverPasswordInput = page.locator('#create-server-password');
    this.dialogCreateButton = page.locator('div[role="dialog"]').getByRole('button', { name: 'Create' });
    this.dialogCancelButton = page.locator('div[role="dialog"]').getByRole('button', { name: 'Cancel' });
  }

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

  async createServer(name: string, options?: { description?: string; topic?: string; sourceId?: string }) {
    if (!await this.serverNameInput.isVisible()) {
      if (await this.searchCreateServerButton.isVisible()) {
        await this.searchCreateServerButton.click();
      } else {
        await this.railCreateServerButton.click();

        if (!await this.serverNameInput.isVisible()) {
          await expect(this.searchCreateServerButton).toBeVisible({ timeout: 10_000 });
          await this.searchCreateServerButton.click();
        }
      }
    }

    await expect(this.serverNameInput).toBeVisible();
    await this.serverNameInput.fill(name);

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

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

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

    await this.dialogCreateButton.click();
  }

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

  async joinServerFromSearch(name: string, options: { acceptPluginDownloads?: boolean } = {}) {
    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();
    }
  }
}
