import { createDepositViaApi, deleteDepositViaApi } from '@/manager/modules/deposit/deposit-api';
import { DepositCreateData } from '@/manager/modules/deposit/deposit-types';
import { DepositCreateDialog } from '@/manager/modules/deposit/views/DepositCreateDialog';
import { DepositDetailsPage } from '@/manager/modules/deposit/views/DepositDetailsPage';
import { DepositListPage } from '@/manager/modules/deposit/views/DepositListPage';
import { test as apiTest } from '@/manager/shared/api-fixtures';
import { Deposit } from '@/shared/types/deposit-types';

interface DepositFixtures {
  depositListPage: DepositListPage;
  depositDetailsPage: DepositDetailsPage;
  depositCreateDialog: DepositCreateDialog;
  createDeposit: (data: DepositCreateData) => Promise<Deposit>;
  trackDepositForTeardown: (id: number) => void;
}

interface DepositInternalFixtures {
  depositTeardown: { depositIds: number[] };
}

export const test = apiTest.extend<DepositFixtures & DepositInternalFixtures>({
  depositListPage: async ({ page }, use) => {
    await use(new DepositListPage(page));
  },

  depositDetailsPage: async ({ page }, use) => {
    await use(new DepositDetailsPage(page));
  },

  depositCreateDialog: async ({ page }, use) => {
    await use(new DepositCreateDialog(page));
  },

  createDeposit: async ({ managerApiRequest, depositTeardown }, use) => {
    await use(async (data) => {
      const deposit = await apiTest.step('setup: create deposit via API', () =>
        createDepositViaApi(managerApiRequest, data)
      );
      depositTeardown.depositIds.push(deposit.id);
      return deposit;
    });
  },

  trackDepositForTeardown: async ({ depositTeardown }, use) => {
    await use((id) => depositTeardown.depositIds.push(id));
  },

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

    await use({ depositIds });

    // 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 deposits via API', () =>
      Promise.all(depositIds.map((id) => deleteDepositViaApi(managerApiRequest, id)))
    );
  },
});

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