import { prisma } from "../constants";
import { CompanyController } from "../controllers/CompanyController";

export const companies = {
  async fetch(identifier: string | number): Promise<CompanyController> {
    const isNumeric =
      typeof identifier === "number" || /^\d+$/.test(String(identifier));

    const company = await prisma.company.findFirst({
      where: isNumeric
        ? { id: Number(identifier) }
        : {
            OR: [{ uid: String(identifier) }, { name: String(identifier) }],
          },
      include: { contacts: true, companyAddresses: true },
    });

    if (!company) throw new Error("Unknown company.");

    return new CompanyController(company);
  },

  async count() {
    return await prisma.company.count();
  },

  /**
   * Fetch Company Pages
   *
   * This is a method to be used to fetch pages of companies used for pagination.
   *
   * @param page - Page number
   * @param rpp  - Records Per Page
   */
  async fetchPages(page: number, rpp: number) {
    page = page.valueOf();
    rpp = rpp.valueOf();

    const skip = (page > 1 ? page : 0) * rpp;
    const take = rpp ?? 30;

    const data = prisma.company.findMany({
      skip,
      take,
    });

    return data;
  },

  /**
   * Search Companies
   *
   * Search companies by identifier, name, or id with pagination support.
   *
   * @param query - Search query string
   * @param page - Page number
   * @param rpp  - Records Per Page
   */
  async search(query: string, page: number, rpp: number) {
    page = page.valueOf();
    rpp = rpp.valueOf();

    const skip = (page > 1 ? page : 0) * rpp;
    const take = rpp ?? 30;

    const numericQuery = parseInt(query, 10);

    const data = prisma.company.findMany({
      where: {
        OR: [
          { name: { contains: query, mode: "insensitive" } },
          { uid: { contains: query, mode: "insensitive" } },
          ...(!isNaN(numericQuery) ? [{ id: numericQuery }] : []),
        ],
      },
      skip,
      take,
    });

    return data;
  },
};
