import { Page } from 'playwright';
import { AbstractLocator, AbstractWidget } from './AbstractWidget';
import { WidgetFindOptions } from './types';
import { expect } from '../fixtures';
import { widgetStep } from '../utils';

export type ButtonFindOptions = WidgetFindOptions & {
  label?: string;
  variant?: string;
  icon?: string;
};

export class ButtonWidget extends AbstractWidget {
  readonly type = 'button';

  constructor(
    protected findOptions: ButtonFindOptions,
    protected readonly page: Page,
    protected readonly parent?: AbstractWidget,
    protected readonly parentLocator?: AbstractLocator
  ) {
    super(findOptions, page, parent, parentLocator);
  }

  find() {
    const { widgetLid, label, icon, variant } = this.findOptions;
    const selectors = [] as string[];
    if (widgetLid) selectors.push(`[data-widgetlid="${widgetLid}"]`);
    if (label) selectors.push(`[label="${label}"]`);
    if (variant) selectors.push(`.btn-${variant}`);

    return this.makeLocator(selectors, {
      has: icon ? this.page.locator(`svg[data-icon="${icon}"]`) : undefined,
    });
  }

  @widgetStep
  async click() {
    try {
      await this.l.waitFor({ state: 'visible' });
      await expect(this.l).not.toContainClass('pe-none');
      await this.l.click();
    } catch (e) {
      throw new Error(
        `${this.type} click failed for options ${JSON.stringify(this.findOptions)}.\nOriginal error: ${e}`
      );
    }
    return this;
  }

  @widgetStep
  async toBeDisabled() {
    await expect(this.l).toBeDisabled();
  }

  @widgetStep
  async notToBeDisabled() {
    await expect(this.l).not.toBeDisabled();
  }
}
