import {
  createCustomerBalanceTransactionViaApi,
  createCustomerViaApi,
  deleteCustomerViaApi,
} from '@/manager/modules/customer/customer-api';
import { CustomerAdjustBalanceData, CustomerCreateData } from '@/manager/modules/customer/customer-types';
import { CustomerCreateDialog } from '@/manager/modules/customer/views/CustomerCreateDialog';
import { CustomerDetailsPage } from '@/manager/modules/customer/views/CustomerDetailsPage';
import { CustomerListPage } from '@/manager/modules/customer/views/CustomerListPage';
import { test as apiTest } from '@/manager/shared/api-fixtures';
import { Customer } from '@/shared/types/customer-types';

interface CustomerFixtures {
  customerListPage: CustomerListPage;
  customerDetailsPage: CustomerDetailsPage;
  customerCreateDialog: CustomerCreateDialog;
  createCustomer: (data: CustomerCreateData) => Promise<Customer>;
  createCustomerBalanceTransaction: (
    customerId: number,
    locationId: number,
    data: CustomerAdjustBalanceData
  ) => Promise<void>;
  trackCustomerForTeardown: (id: number) => void;
}

interface CustomerInternalFixtures {
  customerTeardown: { customerIds: number[] };
}

export const test = apiTest.extend<CustomerFixtures & CustomerInternalFixtures>({
  customerListPage: async ({ page }, use) => {
    await use(new CustomerListPage(page));
  },

  customerDetailsPage: async ({ page }, use) => {
    await use(new CustomerDetailsPage(page));
  },

  customerCreateDialog: async ({ page }, use) => {
    await use(new CustomerCreateDialog(page));
  },

  createCustomer: async ({ managerApiRequest, customerTeardown }, use) => {
    await use(async (data) => {
      const customer = await apiTest.step('setup: create customer via API', () =>
        createCustomerViaApi(managerApiRequest, data)
      );
      customerTeardown.customerIds.push(customer.id);
      return customer;
    });
  },

  createCustomerBalanceTransaction: async ({ managerApiRequest }, use) => {
    await use(async (customerId, locationId, data) => {
      await apiTest.step('setup: create customer balance transaction via API', () =>
        createCustomerBalanceTransactionViaApi(managerApiRequest, customerId, locationId, data)
      );
    });
  },

  trackCustomerForTeardown: async ({ customerTeardown }, use) => {
    await use((id) => customerTeardown.customerIds.push(id));
  },

  customerTeardown: async ({ managerApiRequest }, use) => {
    const customerIds: number[] = [];

    await use({ customerIds });

    // TODO(KIN-4692): Teardown is disabled for now. Deleting these entities kicks off a flood of async
    // backend jobs, and when the job queue backs up, the jobs other e2e tests rely on (e.g. invoice
    // generation) don't run in time and those tests fail. Until the queue pressure is sorted out, we
    // leave all created entities for the env reseed to clean up rather than tearing down here.
    return;

    await apiTest.step('teardown: delete created customers via API', () =>
      Promise.all(customerIds.map((id) => deleteCustomerViaApi(managerApiRequest, id)))
    );
  },
});

export { expect } from '@playwright/test';
