import { BaseDialog } from '@/manager/shared/base/BaseDialog';
import { InvoiceIssueCreditNoteGeneralFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteGeneralFieldSet';
import { InvoiceIssueCreditNoteItemsFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteItemsFieldSet';
import { InvoiceIssueCreditNoteOptionsFieldSet } from '@/manager/modules/invoice/components/InvoiceIssueCreditNoteOptionsFieldSet';
import { InvoiceIssueCreditNoteData } from '@/manager/modules/invoice/invoice-types';
import { InvoiceDetailsPage } from '@/manager/modules/invoice/views/InvoiceDetailsPage';
import { InvoiceIssueCreditNoteConfirmDialog } from '@/manager/modules/invoice/views/InvoiceIssueCreditNoteConfirmDialog';
import { getDialogErrorsHost, getLoadingSpinnerHost, getSnackbarHost } from '@/manager/shared/utils/locator-utils';
import { Page } from '@playwright/test';

export class InvoiceIssueCreditNoteDialog extends BaseDialog {
  readonly generalFieldSet = new InvoiceIssueCreditNoteGeneralFieldSet(this.main);
  readonly itemsFieldSet = new InvoiceIssueCreditNoteItemsFieldSet(this.main);
  readonly optionsFieldSet = new InvoiceIssueCreditNoteOptionsFieldSet(this.main);
  readonly errors = getDialogErrorsHost(this.main);
  readonly loadingSpinner = getLoadingSpinnerHost(this.main);
  readonly snackbar = getSnackbarHost(this.host, 'Credit note successfully issued!');

  constructor(host: Page) {
    super(host, 'invoice-issue-credit-note-dialog');
  }

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

  async fill(data: InvoiceIssueCreditNoteData): Promise<void> {
    await this.generalFieldSet.reasonTextAreaField.fill(data.reason);
    await this.itemsFieldSet.list.select(data.items);

    if (data.option != null) {
      await this.optionsFieldSet.radioGroup.check(data.option);
    }
  }

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

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