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

export type NavTileFindOptions = WidgetFindOptions & {
  label?: string;
  exact?: boolean;
  variant?: string;
  icon?: string;
};

export class NavTileWidget extends AbstractWidget {
  readonly type = 'navTile';

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

  find() {
    const { label, icon, variant, exact } = this.findOptions;

    let tile = this.makeLocator();

    if (label) {
      tile = tile.filter({
        hasText: exact ? new RegExp(`^${label}$`) : label,
      });
    }
    if (icon)
      tile = tile.filter({
        has: this.page.locator(`svg[data-icon="${icon}"]`),
      });
    if (variant)
      tile = tile.filter({ has: this.page.locator(`div.bg-${variant}`) });

    return tile;
  }

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