import { createInsuranceViaApi, deleteInsuranceViaApi } from '@/manager/modules/insurance/insurance-api';
import { InsuranceCreateData } from '@/manager/modules/insurance/insurance-types';
import { InsuranceCreateDialog } from '@/manager/modules/insurance/views/InsuranceCreateDialog';
import { InsuranceDetailsPage } from '@/manager/modules/insurance/views/InsuranceDetailsPage';
import { InsuranceListPage } from '@/manager/modules/insurance/views/InsuranceListPage';
import { test as apiTest } from '@/manager/shared/api-fixtures';
import { Insurance } from '@/shared/types/insurance-types';

interface InsuranceFixtures {
  insuranceListPage: InsuranceListPage;
  insuranceDetailsPage: InsuranceDetailsPage;
  insuranceCreateDialog: InsuranceCreateDialog;
  createInsurance: (data: InsuranceCreateData) => Promise<Insurance>;
  trackInsuranceForTeardown: (id: number) => void;
}

interface InsuranceInternalFixtures {
  insuranceTeardown: { insuranceIds: number[] };
}

export const test = apiTest.extend<InsuranceFixtures & InsuranceInternalFixtures>({
  insuranceListPage: async ({ page }, use) => {
    await use(new InsuranceListPage(page));
  },

  insuranceDetailsPage: async ({ page }, use) => {
    await use(new InsuranceDetailsPage(page));
  },

  insuranceCreateDialog: async ({ page }, use) => {
    await use(new InsuranceCreateDialog(page));
  },

  createInsurance: async ({ managerApiRequest, insuranceTeardown }, use) => {
    await use(async (data) => {
      const insurance = await apiTest.step('setup: create insurance via API', () =>
        createInsuranceViaApi(managerApiRequest, data)
      );
      insuranceTeardown.insuranceIds.push(insurance.id);
      return insurance;
    });
  },

  trackInsuranceForTeardown: async ({ insuranceTeardown }, use) => {
    await use((id) => insuranceTeardown.insuranceIds.push(id));
  },

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

    await use({ insuranceIds });

    await apiTest.step('teardown: delete created insurances via API', () =>
      Promise.all(insuranceIds.map((id) => deleteInsuranceViaApi(managerApiRequest, id)))
    );
  },
});

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