import { getUnitTypeBookingPlan } from '@/manager/modules/booking/booking-factories';
import { test } from '@/manager/modules/booking/booking-fixtures';
import { toBookingItemsDetails } from '@/manager/modules/booking/booking-mappers';
import { BookingAdjustmentData, BookingCreateData } from '@/manager/modules/booking/booking-types';
import { BookingDetailsPage } from '@/manager/modules/booking/views/BookingDetailsPage';
import { expectSingleLocatorToHaveText } from '@/manager/shared/utils/expect-utils';
import { formatBillingPeriod, formatCurrency } from '@/shared/utils/formatters';
import { expect } from '@/shared/utils/matchers';

function getPlanSwitchAdjustment(data: BookingCreateData): BookingAdjustmentData {
  return {
    plan: getUnitTypeBookingPlan(data.unitType.unitType, data.unitType.plan.period, 'Advanced'),
    applyType: 'end_current_period',
  };
}

const entryPoints = [
  {
    title: 'deletes the adjustment from the notification banner',
    openDeleteDialog: (page: BookingDetailsPage) => page.openBookingAdjustmentDeleteDialogFromNotification(),
  },
  {
    title: 'deletes the adjustment from the actions menu',
    openDeleteDialog: (page: BookingDetailsPage) => page.openBookingAdjustmentDeleteDialog(),
  },
];

for (const { title, openDeleteDialog } of entryPoints) {
  test(title, async ({ setupBookingCreateData, createBooking, createBookingAdjustment, bookingDetailsPage }) => {
    const data = await setupBookingCreateData();
    const booking = await createBooking(data);
    const originalPlan = data.unitType.plan;
    const { currency } = data.location;
    const originalPlanLabel = formatBillingPeriod(originalPlan.period, originalPlan.amount, originalPlan.name);
    const amountExclVat = formatCurrency(toBookingItemsDetails(data).totals.exclVat, currency);

    await createBookingAdjustment(booking, getPlanSwitchAdjustment(data));

    await bookingDetailsPage.goto(booking.id);

    const dialog = await test.step('open the delete dialog', () => openDeleteDialog(bookingDetailsPage));

    await test.step('delete the adjustment', () => dialog.delete());

    await test.step('verify the adjustment is removed', async () => {
      await bookingDetailsPage.reload();
      await expectSingleLocatorToHaveText(bookingDetailsPage.billingCard.bookingPlan, originalPlanLabel);
      await expectSingleLocatorToHaveText(bookingDetailsPage.billingCard.amountExclVat, amountExclVat);
      await expect(bookingDetailsPage.adjustmentNotificationCard.main).toBeHidden();
    });
  });
}
