import { createCustomerViaApi, deleteCustomerViaApi } from '@/manager/modules/customer/customer-api';
import { 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>;
  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;
    });
  },

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

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

    await use({ customerIds });

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

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