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 { BookingCreateData } from '@/manager/modules/booking/booking-types';
import { BookingDetailsPage } from '@/manager/modules/booking/views/BookingDetailsPage';
import { getSnackbarHost, getDialogErrorsHost, getLoadingSpinnerHost } from '@/manager/shared/utils/locator-utils';
import { getDetailsPageRegExpUrl } from '@/manager/shared/utils/url-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 loadingSpinner = getLoadingSpinnerHost(this.main);
  readonly createdSnackbar = getSnackbarHost(this.host, 'Booking saved successfully');
  readonly paymentLimitSnackbar = getSnackbarHost(this.host, 'Max billing amount exceeded for payment method type');

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

  async goto(): Promise<void> {
    await this.host.goto('/bookings/create');
  }

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

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

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

    if (data.customer.locations.length > 1) {
      await this.generalFieldSet.locationAutocomplete.fill(data.location.name);
    }

    await this.generalFieldSet.moveInDatePicker.fill(data.moveInDate);

    if (data.note != null) {
      await this.generalFieldSet.noteTextAreaField.fill(data.note);
    }

    await this.productsFieldSet.unitTypePickerTable.select(data.unitType, data.unit);

    if (data.insurance) {
      await this.productsFieldSet.insurancePickerTable.select(data.insurance);
    }

    if (data.recurringProducts) {
      await this.productsFieldSet.productRecurringPickerTable.add(data.recurringProducts);
    }

    if (data.oneTimeProducts) {
      await this.productsFieldSet.productOneTimePickerTable.add(data.oneTimeProducts);
    }

    if (data.discount) {
      await this.productsFieldSet.discountPickerTable.select(data.discount);
    }

    if (data.deposit) {
      await this.productsFieldSet.depositPickerTable.select(data.deposit, data.location);
    }

    await this.paymentFieldSet.radioGroup.fill(data.payment);
  }

  async submit(): Promise<void> {
    await this.loadingSpinner.waitFor({ state: 'hidden' });
    await this.submitButton.click();
  }
}
