import { BaseDialog } from '@/manager/shared/base/BaseDialog';
import { BookingCreateGeneralFieldSet } from '@/manager/modules/booking/components/BookingCreateGeneralFieldSet';
import { BookingCreatePaymentFieldSet } from '@/manager/modules/booking/components/BookingCreatePaymentFieldSet';
import { BookingCreateProductsFieldSet } from '@/manager/modules/booking/components/BookingCreateProductsFieldSet';
import { IBookingCreateData } from '@/manager/modules/booking/types/booking-types';
import { BookingDetailsPage } from '@/manager/modules/booking/views/BookingDetailsPage';
import { getSnackbarHost, getDialogErrorsHost } from '@/manager/shared/utils/host-utils';
import { getDetailsPageRegExpUrl } from '@/manager/shared/utils/url-utils';
import { formatBillingPeriod } from '@/shared/utils/format-utils';
import { Page } from '@playwright/test';

export class BookingCreateDialog extends BaseDialog {
  readonly generalFieldSet = new BookingCreateGeneralFieldSet(this.main);
  readonly productsFieldSet = new BookingCreateProductsFieldSet(this.main);
  readonly paymentFieldSet = new BookingCreatePaymentFieldSet(this.main);
  readonly errors = getDialogErrorsHost(this.main);
  readonly snackbar = getSnackbarHost(this.host, 'Booking saved successfully');

  constructor(host: Page) {
    super(host, 'booking-create-dialog');
  }

  async create(data: IBookingCreateData): Promise<BookingDetailsPage> {
    await this.fill(data);
    return this.submit();
  }

  async createWithoutFillingCustomerEmail(data: IBookingCreateData): Promise<BookingDetailsPage> {
    await this.fillWithoutCustomerEmail(data);
    return this.submit();
  }

  async fill(data: IBookingCreateData): Promise<void> {
    await this.generalFieldSet.customerAutocomplete.fill(data.customer.email);
    await this.fillWithoutCustomerEmail(data);
  }

  async fillWithoutCustomerEmail(data: IBookingCreateData): Promise<void> {
    data.customer.locations.length > 1 && (await this.generalFieldSet.locationAutocomplete.fill(data.location.name));
    await this.generalFieldSet.moveInDatePicker.fill(data.moveInDate);
    data.note != null && (await this.generalFieldSet.noteTextAreaField.fill(data.note));
    await this.productsFieldSet.unitTypeAutocomplete.fill(data.unitType.name);
    await this.productsFieldSet.bookingPlanAutocomplete.fill(
      formatBillingPeriod(
        data.unitType.billing.type,
        data.unitType.billing.plan.amount,
        data.unitType.billing.plan.name
      )
    );
    await this.productsFieldSet.unitAutocomplete.fill(data.unit);
    data.insurance && (await this.productsFieldSet.insurancePickerTable.select(data.insurance.name));
    data.discount && (await this.productsFieldSet.discountPickerTable.select(data.discount.name));
    await this.paymentFieldSet.radioGroup.fill(data.payment);
  }

  async submit(): Promise<BookingDetailsPage> {
    await Promise.all([
      this.snackbar.waitFor(),
      this.host.waitForURL(getDetailsPageRegExpUrl('bookings')),
      this.submitButton.click(),
    ]);
    return new BookingDetailsPage(this.host);
  }
}
