import { BaseDialog } from '@/manager/shared/base/BaseDialog';
import { DiscountBillingPlanCard } from '@/manager/modules/discount/components/DiscountBillingPlanCard';
import { DiscountCodeFieldSet } from '@/manager/modules/discount/components/DiscountCodeFieldSet';
import { DiscountDurationFieldSet } from '@/manager/modules/discount/components/DiscountDurationFieldSet';
import { DiscountGeneralFieldSet } from '@/manager/modules/discount/components/DiscountGeneralFieldSet';
import { DiscountProductCard } from '@/manager/modules/discount/components/DiscountProductCard';
import { DiscountRestrictionsFieldSet } from '@/manager/modules/discount/components/DiscountRestrictionsFieldSet';
import { DiscountTypeFieldSet } from '@/manager/modules/discount/components/DiscountTypeFieldSet';
import { IDiscountCreateData } from '@/manager/modules/discount/types/discount-types';
import { DiscountDetailPage } from '@/manager/modules/discount/views/DiscountDetailPage';
import { getDialogErrorsHost, getSnackbarHost } from '@/manager/shared/utils/host-utils';
import { getDetailsPageRegExpUrl } from '@/manager/shared/utils/url-utils';
import { Locator, Page } from '@playwright/test';

// TODO: due to a Vue 3 fetch dynamically imported module bug the success snackbar check must be removed for now

export class DiscountCreateDialog extends BaseDialog {
  readonly generalFieldSet: DiscountGeneralFieldSet;
  readonly productCard: DiscountProductCard;
  readonly billingPlanCard: DiscountBillingPlanCard;
  readonly typeFieldSet: DiscountTypeFieldSet;
  readonly durationFieldSet: DiscountDurationFieldSet;
  readonly restrictionsFieldSet: DiscountRestrictionsFieldSet;
  readonly codeFieldSet: DiscountCodeFieldSet;
  readonly errors: Locator;
  readonly snackbar: Locator;

  constructor(host: Page) {
    super(host, 'discount-create-dialog');
    this.generalFieldSet = new DiscountGeneralFieldSet(this.main);
    this.productCard = new DiscountProductCard(this.main);
    this.billingPlanCard = new DiscountBillingPlanCard(this.main);
    this.typeFieldSet = new DiscountTypeFieldSet(this.main);
    this.durationFieldSet = new DiscountDurationFieldSet(this.main);
    this.restrictionsFieldSet = new DiscountRestrictionsFieldSet(this.main);
    this.codeFieldSet = new DiscountCodeFieldSet(this.main);
    this.errors = getDialogErrorsHost(this.main);
    this.snackbar = getSnackbarHost(this.host, 'Discount created successfully');
  }

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

  async fill(data: IDiscountCreateData): Promise<void> {
    await this.generalFieldSet.nameTextField.fill(data.name);
    await this.generalFieldSet.locationAutocomplete.fill(data.location.name);

    const productDialog = await this.productCard.openDiscountEditProductsDialog(false);

    if (data.productsSelection.all) {
      await productDialog.addAll();
    } else {
      await productDialog.add(data.productsSelection.items);
    }

    await productDialog.submit();

    const billingPlanDialog = await this.billingPlanCard.openDiscountEditBillingPlansDialog(false);

    if (data.billingPlansSelection.all) {
      await billingPlanDialog.addAll();
    } else {
      await billingPlanDialog.add(data.billingPlansSelection.items);
    }

    await billingPlanDialog.submit();

    await this.typeFieldSet.typeRadioGroup.check(data.type);

    if (data.type === 'percentage') {
      await this.typeFieldSet.percentageTypeNumberField.fill(data.value);
    } else {
      await this.typeFieldSet.fixedTypeNumberField.fill(data.value);
    }

    await this.durationFieldSet.durationRadioGroup.check(data.duration.option);

    if (data.duration.option === 'multiple_months' && data.duration.amount != null) {
      await this.durationFieldSet.multipleMonthsDurationNumberField.fill(data.duration.amount);
    }

    if (data.expirationDate) {
      await this.restrictionsFieldSet.expiryDateCheckbox.set(true);
      await this.restrictionsFieldSet.expiryDateTimePicker.fill(data.expirationDate);
    }

    if (data.usageLimit != null) {
      await this.restrictionsFieldSet.usageLimitCheckbox.set(true);
      await this.restrictionsFieldSet.usageLimitNumberField.fill(data.usageLimit);
    }

    if (data.code.active && data.code.value) {
      await this.codeFieldSet.codeSection.codeSwitch.set(data.code.active);
      await this.codeFieldSet.codeSection.codeTextField.fill(data.code.value);
    }
  }

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