import { ICustomerCreateData } from '@/manager/modules/customer/types/customer-types';
import { CustomerListPage } from '@/manager/modules/customer/views/CustomerListPage';
import { customerTableColumnTestIds } from '@/manager/modules/ui/data-table/data/data-table-column-test-ids';
import {
  expectDataTableTextColumnToHaveText,
  expectDataTableChipsColumnToHaveText,
} from '@/manager/modules/ui/data-table/utils/data-table-expect-utils';
import { expectSingleLocatorToHaveText, expectMultiLocatorToHaveText } from '@/manager/shared/utils/expect-utils';
import { formatDate, formatName, formatPhone, formatAddress, formatCurrency } from '@/shared/utils/format-utils';
import { expect } from '@/shared/utils/matcher-utils';

export async function expectCustomerToNotBeCreated(page: CustomerListPage, data: ICustomerCreateData): Promise<void> {
  // filter list
  await page.searchTextField.fill(data.email);

  // check list (customer data should not exist)
  await expect(page.dataTable.getRows()).toHaveCount(0);

  // open customer create dialog
  const createDialog = await page.openCustomerCreateDialog();

  // fill customer create data
  await createDialog.fill(data);

  // try to create customer
  await createDialog.submitButton.click();

  // check customer create dialog
  await expect(createDialog.errors).toHaveCountGreaterThan(0);
}

export async function expectCustomerToBeCreated(startPage: CustomerListPage, data: ICustomerCreateData): Promise<void> {
  // filter list
  await startPage.searchTextField.fill(data.email);

  // check list (customer data should not exist)
  await expect(startPage.dataTable.getRows()).toHaveCount(0);

  // open customer create dialog
  const createDialog = await startPage.openCustomerCreateDialog();

  // create customer
  const detailsPage = await createDialog.create(data);

  // define helpers
  const customerCreatedAt = formatDate(new Date());
  const customerFullName = formatName(data.firstName, data.lastName);
  const customerTitle = data.type === 'business' ? data.companyName : customerFullName;
  const customerPhone = formatPhone(data.phone);

  // check details page (customer data should exist)
  await expectSingleLocatorToHaveText(detailsPage.title, customerTitle);
  await expectSingleLocatorToHaveText(detailsPage.status, 'lead');
  await expectMultiLocatorToHaveText(detailsPage.generalCard.locations, data.locations);
  await expectSingleLocatorToHaveText(detailsPage.generalCard.type, data.type);

  if (data.type === 'business') {
    await expectSingleLocatorToHaveText(detailsPage.generalCard.companyName, data.companyName);
    await expectSingleLocatorToHaveText(detailsPage.generalCard.vatNumber, data.vatNumber);
  } else {
    await expect(detailsPage.generalCard.companyName).toBeHidden();
    await expect(detailsPage.generalCard.vatNumber).toBeHidden();
  }

  await expectSingleLocatorToHaveText(detailsPage.generalCard.name, customerFullName);
  await expectSingleLocatorToHaveText(detailsPage.generalCard.email, data.email);
  await expectSingleLocatorToHaveText(detailsPage.generalCard.phoneNumber, customerPhone);
  await expectSingleLocatorToHaveText(detailsPage.generalCard.language, data.language.id);
  await expectSingleLocatorToHaveText(
    detailsPage.generalCard.address,
    formatAddress(data.street, data.postalCode, data.city, data.country.abbreviation ?? data.country.name)
  );
  await expect(detailsPage.detailsCard.customerId).not.toBeEmpty();
  await expectSingleLocatorToHaveText(detailsPage.detailsCard.createdAt, customerCreatedAt);
  await expectSingleLocatorToHaveText(detailsPage.detailsCard.totalSpent, formatCurrency(0));
  await expect(detailsPage.detailsCard.paymentMethods).toHaveCount(0);
  await expect(detailsPage.bookingsCard.dataTable.getRows()).toHaveCount(0);
  await expect(detailsPage.invoicesCard.dataTable.getRows()).toHaveCount(0);

  // define helpers
  const customerId = await detailsPage.detailsCard.customerId.innerText();

  // return to customer list page
  const listPage = await detailsPage.returnToCustomerListPage();

  // filter list
  await listPage.searchTextField.fill(data.email);

  // check list (customer data should exist)
  await expect(listPage.dataTable.getRows()).toHaveCount(1);
  await expectDataTableTextColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.id, customerId);
  await expectDataTableTextColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.name, customerTitle);
  await expectDataTableChipsColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.locations, data.locations);
  await expectDataTableTextColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.email, data.email);
  await expectDataTableChipsColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.status, 'lead');
  await expectDataTableChipsColumnToHaveText(listPage.dataTable, customerTableColumnTestIds.hasPastDueInvoices, 'none');
  await expectDataTableTextColumnToHaveText(
    listPage.dataTable,
    customerTableColumnTestIds.createdAt,
    customerCreatedAt
  );
}
