import { BookingPlan } from '@/shared/types/booking-plan-types';
import { DataTable } from '@/manager/modules/ui/data-table/components/DataTable';
import { bookingPlanTableColumnTestIds } from '@/manager/modules/ui/data-table/data/data-table-column-test-ids';
import { expectSingleLocatorToHaveText } from '@/manager/shared/utils/expect-utils';
import { formatBillingPeriod, formatCurrencyWithExtendedPrecision, formatPercentage } from '@/shared/utils/formatters';
import { decreaseByPercentage } from '@/shared/utils/math-utils';
import { expect } from '@playwright/test';

type BookingPlansTableVariant = 'unitType' | 'insurance' | 'recurringProduct';

export async function verifyBookingPlansTable(
  table: DataTable,
  plans: BookingPlan[],
  currency: string,
  variant: BookingPlansTableVariant
): Promise<void> {
  const hidesNameColumn = variant === 'insurance' || variant === 'recurringProduct';
  const orderedPlans = [...plans].reverse();
  const defaultVisiblePlans = 5;
  const maxVisiblePlans = 25;

  if (plans.length > defaultVisiblePlans) {
    await table.selectRowsPerPage(maxVisiblePlans);
  }

  await expect(table.getRows()).toHaveCount(Math.min(plans.length, maxVisiblePlans));

  await expect(table.getColumnheader(bookingPlanTableColumnTestIds.operations)).toBeHidden();

  for (let index = 0; index < orderedPlans.length; index++) {
    const plan = orderedPlans[index];
    const priceExclVat = plan.discount ? decreaseByPercentage(plan.priceExclVat, plan.discount) : plan.priceExclVat;
    const periodPriceExclVat = priceExclVat * plan.amount;

    if (hidesNameColumn) {
      await expect(table.getColumn(bookingPlanTableColumnTestIds.name)).toBeHidden();
    } else {
      await expectSingleLocatorToHaveText(
        table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.name),
        plan.name
      );
    }

    await expectSingleLocatorToHaveText(
      table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.billingPeriod),
      formatBillingPeriod(plan.period, plan.amount)
    );
    await expectSingleLocatorToHaveText(
      table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.discount),
      formatPercentage(plan.discount ?? 0)
    );
    await expectSingleLocatorToHaveText(
      table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.priceExclVat),
      formatCurrencyWithExtendedPrecision(priceExclVat, currency)
    );
    await expectSingleLocatorToHaveText(
      table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.periodPriceExclVat),
      formatCurrencyWithExtendedPrecision(periodPriceExclVat, currency)
    );
    await expectSingleLocatorToHaveText(
      table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.status),
      plan.publish ? 'published' : 'unpublished'
    );

    await expect(table.getRowColumnByIndex(index, bookingPlanTableColumnTestIds.activeBookings)).toBeVisible();
  }
}
