import { ICustomer } from '@/manager/modules/customer/types/customer-types';
import { CustomerDetailsPage } from '@/manager/modules/customer/views/CustomerDetailsPage';
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 {
  formatAddress,
  formatCurrency,
  formatDate,
  formatId,
  formatName,
  formatPaymentMethod,
  formatPhone,
} from '@/shared/utils/format-utils';
import { expect } from '@playwright/test';

export async function expectCustomerDetailsPageAndThenListPageToDisplayCorrectData(
  startPage: CustomerDetailsPage,
  customer: ICustomer
): Promise<CustomerListPage> {
  await expectCustomerDetailsPageToDisplayCorrectData(startPage, customer);
  const listPage = await startPage.returnToCustomerListPage();
  await expectCustomerListPageToDisplayCorrectData(listPage, customer);
  return listPage;
}

export async function expectCustomerListPageAndThenDetailsPageToDisplayCorrectData(
  startPage: CustomerListPage,
  customer: ICustomer
): Promise<CustomerDetailsPage> {
  await expectCustomerListPageToDisplayCorrectData(startPage, customer);
  const detailsPage = await startPage.goToCustomerDetailsPage(0);
  await expectCustomerDetailsPageToDisplayCorrectData(detailsPage, customer);
  return detailsPage;
}

export async function expectCustomerDetailsPageToDisplayCorrectData(page: CustomerDetailsPage, customer: ICustomer) {
  // define helpers
  const customerId = formatId(customer.id, '-', 4);
  const customerCreatedAt = formatDate(new Date());
  const customerFullName = formatName(customer.firstName, customer.lastName);
  const customerTitle = customer.type === 'business' ? customer.companyName : customerFullName;
  const customerPhone = formatPhone(customer.phone);
  const customerTotalSpent = formatCurrency(customer.totalSpent);
  const customerAddress = formatAddress(
    customer.street,
    customer.postalCode,
    customer.city,
    customer.country.abbreviation ?? customer.country.name
  );
  const customerPaymentMethods = customer.paymentMethods?.map((method) => formatPaymentMethod(method, true));

  // check details
  await expectSingleLocatorToHaveText(page.title, customerTitle);
  await expectSingleLocatorToHaveText(page.status, customer.status);
  await expectMultiLocatorToHaveText(page.generalCard.locations, customer.locations);
  await expectSingleLocatorToHaveText(page.generalCard.type, customer.type);

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

  await expectSingleLocatorToHaveText(page.generalCard.name, customerFullName);
  await expectSingleLocatorToHaveText(page.generalCard.email, customer.email);
  await expectSingleLocatorToHaveText(page.generalCard.phoneNumber, customerPhone);
  await expectSingleLocatorToHaveText(page.generalCard.language, customer.language.id);
  await expectSingleLocatorToHaveText(page.generalCard.address, customerAddress);
  await expectSingleLocatorToHaveText(page.detailsCard.customerId, customerId);
  await expectSingleLocatorToHaveText(page.detailsCard.createdAt, customerCreatedAt);
  await expectSingleLocatorToHaveText(page.detailsCard.totalSpent, customerTotalSpent);
  customerPaymentMethods
    ? await expectMultiLocatorToHaveText(page.detailsCard.paymentMethods, customerPaymentMethods)
    : await expect(page.detailsCard.paymentMethods).toHaveCount(0);
  // TODO: expect customer bookings data table check
  // TODO: expect customer invoices data table check
}

export async function expectCustomerListPageToDisplayCorrectData(page: CustomerListPage, customer: ICustomer) {
  // define helpers
  const customerId = formatId(customer.id, '-', 4);
  const customerCreatedAt = formatDate(new Date());
  const customerFullName = formatName(customer.firstName, customer.lastName);
  const customerTitle = customer.type === 'business' ? customer.companyName : customerFullName;

  // filter list
  await page.searchTextField.fill(customer.email);

  // check list
  await expect(page.dataTable.getRows()).toHaveCount(1);
  await expectDataTableTextColumnToHaveText(page.dataTable, customerTableColumnTestIds.id, customerId);
  await expectDataTableTextColumnToHaveText(page.dataTable, customerTableColumnTestIds.name, customerTitle);
  await expectDataTableChipsColumnToHaveText(page.dataTable, customerTableColumnTestIds.locations, customer.locations);
  await expectDataTableTextColumnToHaveText(page.dataTable, customerTableColumnTestIds.email, customer.email);
  await expectDataTableChipsColumnToHaveText(page.dataTable, customerTableColumnTestIds.status, customer.status);
  // TODO: expect customer has past due invoices column (e.g. none) check
  await expectDataTableTextColumnToHaveText(page.dataTable, customerTableColumnTestIds.createdAt, customerCreatedAt);
}
