import { IBookingCreatePayment, IBookingCreatePaymentOption } from '@/manager/modules/booking/types/booking-types';
import { AddManualPaymentMethodForm } from '@/manager/modules/ui/payment-method/components/AddManualPaymentMethodForm';
import { AddPaymentMethodDialog } from '@/manager/modules/ui/payment-method/views/AddPaymentMethodDialog';
import { RadioButton } from '@/manager/shared/components/RadioButton';
import { getRadioGroupHost, getSegmentedCardHost } from '@/manager/shared/utils/host-utils';
import { BaseComponent } from '@/shared/base/BaseComponent';
import { formatPaymentMethod } from '@/shared/utils/format-utils';

export class BookingCreatePaymentRadioGroup extends BaseComponent {
  readonly main = getRadioGroupHost(this.host);
  readonly afterFirstInvoicePaymentSection = this.main.getByTestId('after-first-invoice-payment-option');
  readonly afterFirstInvoiceRadioButton = new RadioButton(this.afterFirstInvoicePaymentSection);
  readonly automaticPaymentSection = this.main.getByTestId('automatic-payment-option');
  readonly automaticRadioButton = new RadioButton(this.automaticPaymentSection);
  readonly paymentMethodsLoading = this.automaticPaymentSection.getByTestId('payment-methods-dropdown-loading');
  readonly addPaymentMethodButton = this.automaticPaymentSection.getByTestId('add-payment-method-button');
  readonly manualPaymentSection = this.main.getByTestId('manual-payment-option');
  readonly manualPaymentRadioButton = new RadioButton(this.manualPaymentSection);
  readonly addManualPaymentMethodForm = new AddManualPaymentMethodForm(this.manualPaymentSection);

  async fill(data: IBookingCreatePayment): Promise<void> {
    await this.check(data.option);

    if (data.option === 'charge_automatically' && data.method) {
      const paymentMethod = formatPaymentMethod(data.method);
      const segmentedCard = getSegmentedCardHost(this.automaticPaymentSection, paymentMethod);

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

      if (await segmentedCard.isHidden()) {
        const dialog = await this.openAddPaymentMethodDialog();
        await Promise.all([segmentedCard.waitFor(), dialog.add(data.method)]);
      }

      await segmentedCard.click();
    } else if (data.option === 'pay_manually' && data.manual) {
      await this.addManualPaymentMethodForm.fill(data.manual);
    }
  }

  private check(option: IBookingCreatePaymentOption): Promise<void> {
    switch (option) {
      case 'charge_automatically_after_first_invoice':
        return this.afterFirstInvoiceRadioButton.check();
      case 'charge_automatically':
        return this.automaticRadioButton.check();
      case 'pay_manually':
        return this.manualPaymentRadioButton.check();
    }
  }

  private async openAddPaymentMethodDialog(): Promise<AddPaymentMethodDialog> {
    await this.addPaymentMethodButton.click();
    return new AddPaymentMethodDialog(this.host.page());
  }
}
