import { BaseDialog } from '@/manager/shared/base/BaseDialog';
import { InvoiceCreateGeneralFieldSet } from '@/manager/modules/invoice/components/InvoiceCreateGeneralFieldSet';
import { InvoiceCreatePaymentFieldSet } from '@/manager/modules/invoice/components/InvoiceCreatePaymentFieldSet';
import { InvoiceCreateProductsFieldSet } from '@/manager/modules/invoice/components/InvoiceCreateProductsFieldSet';
import { InvoiceCreateData } from '@/manager/modules/invoice/invoice-types';
import { InvoiceCreateConfirmDialog } from '@/manager/modules/invoice/views/InvoiceCreateConfirmDialog';
import { InvoiceDetailsPage } from '@/manager/modules/invoice/views/InvoiceDetailsPage';
import { getDialogErrorsHost, getLoadingSpinnerHost, getSnackbarHost } from '@/manager/shared/utils/locator-utils';
import { getDetailsPageRegExpUrl } from '@/manager/shared/utils/url-utils';
import { Page } from '@playwright/test';

export class InvoiceCreateDialog extends BaseDialog {
  readonly generalFieldSet = new InvoiceCreateGeneralFieldSet(this.main);
  readonly productsFieldSet = new InvoiceCreateProductsFieldSet(this.main);
  readonly paymentFieldSet = new InvoiceCreatePaymentFieldSet(this.main);
  readonly errors = getDialogErrorsHost(this.main);
  readonly loadingSpinner = getLoadingSpinnerHost(this.main);
  readonly snackbar = getSnackbarHost(this.host, 'Invoice has been created successfully');

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

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

  async create(data: InvoiceCreateData): Promise<InvoiceDetailsPage> {
    await this.fill(data);
    await this.submit();
    return this.confirm();
  }

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

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

    if (data.memo != null) {
      await this.generalFieldSet.memoTextAreaField.fill(data.memo);
    }

    if (data.footer != null) {
      await this.generalFieldSet.footerTextAreaField.fill(data.footer);
    }

    await this.productsFieldSet.list.select(data.products);
    await this.paymentFieldSet.radioGroup.fill(data.payment);
  }

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

  async confirm(): Promise<InvoiceDetailsPage> {
    const confirmDialog = new InvoiceCreateConfirmDialog(this.host);
    await Promise.all([
      this.snackbar.waitFor(),
      this.host.waitForURL(getDetailsPageRegExpUrl('invoices')),
      confirmDialog.submit(),
    ]);
    return new InvoiceDetailsPage(this.host);
  }
}
