import { PaymentMethodAddDialog } from '@/manager/modules/ui/payment-method/views/PaymentMethodAddDialog';
import { getSegmentedCardHost } from '@/manager/shared/utils/locator-utils';
import { BaseComponent } from '@/shared/base/BaseComponent';
import { PaymentMethod } from '@/shared/modules/payment-method/payment-method-types';
import { formatPaymentMethodMaskedNumber } from '@/shared/utils/formatters';

export class PaymentMethodAddForm extends BaseComponent {
  readonly loading = this.host.getByTestId('payment-methods-dropdown-loading');
  readonly addButton = this.host.getByTestId('add-payment-method-button');

  async select(method: PaymentMethod): Promise<void> {
    const segmentedCard = getSegmentedCardHost(this.host, this.formatSegmentedCardLabel(method));

    await this.loading.waitFor({ state: 'hidden' });

    if (await segmentedCard.isHidden()) {
      await this.add(method);
    } else {
      await segmentedCard.click();
    }
  }

  async add(method: PaymentMethod): Promise<void> {
    const segmentedCard = getSegmentedCardHost(this.host, this.formatSegmentedCardLabel(method));

    await this.loading.waitFor({ state: 'hidden' });

    const dialog = await this.openAddDialog();
    await Promise.all([segmentedCard.waitFor(), dialog.add(method)]);
  }

  private async openAddDialog(): Promise<PaymentMethodAddDialog> {
    await this.addButton.click();
    return new PaymentMethodAddDialog(this.host.page());
  }

  private formatSegmentedCardLabel(method: PaymentMethod): string {
    let label: string;

    switch (method.kind) {
      case 'sepa':
        label = 'IBAN';
        break;
      case 'card':
        label = 'Card';
        break;
      case 'bacs':
        label = 'Bacs Direct Debit';
        break;
    }

    return `${label} ${formatPaymentMethodMaskedNumber(method)}`;
  }
}
