import { Collection } from "@discordjs/collection";
import { connectWiseApi } from "../../../constants";
import { CatalogItem } from "./catalog.types.ts";

export interface CatalogSummary {
  id: number;
  _info?: Record<string, string>;
}

export interface InventoryEntry {
  id: number;
  onHand: number;
}

export const catalogCw = {
  countItems: async (): Promise<number> => {
    const response = await connectWiseApi.get("/procurement/catalog/count");
    return response.data.count;
  },
  fetchAllCatalogSummary: async (): Promise<
    Collection<number, CatalogSummary>
  > => {
    const allItems = new Collection<number, CatalogSummary>();
    const pageSize = 1000;

    const count = await catalogCw.countItems();
    const totalPages = Math.ceil(count / pageSize);

    for (let page = 0; page < totalPages; page++) {
      const response = await connectWiseApi.get(
        `/procurement/catalog?page=${page + 1}&pageSize=${pageSize}&fields=id,_info`,
      );
      const items: CatalogSummary[] = response.data;

      for (const item of items) {
        allItems.set(item.id, item);
      }
    }

    return allItems;
  },
  fetchInventoryOnHand: async (cwCatalogId: number): Promise<number> => {
    const response = await connectWiseApi.get(
      `/procurement/catalog/${cwCatalogId}/inventory?fields=onHand`,
    );
    const entries: InventoryEntry[] = response.data;
    return entries.reduce((sum, e) => sum + (e.onHand || 0), 0);
  },
  fetchAllItemsFromCw: async (): Promise<Collection<number, CatalogItem>> => {
    const allItems = new Collection<number, CatalogItem>();
    const pageSize = 1000;

    const count = await catalogCw.countItems();
    const totalPages = Math.ceil(count / pageSize);

    for (let page = 0; page < totalPages; page++) {
      const response = await connectWiseApi.get(
        `/procurement/catalog?page=${page + 1}&pageSize=${pageSize}`,
      );
      const items: CatalogItem[] = response.data;

      for (const item of items) {
        allItems.set(item.id, item);
      }
    }

    return allItems;
  },
  fetchByCatalogId: async (cwCatalogId: number): Promise<CatalogItem> => {
    try {
      const response = await connectWiseApi.get(
        `/procurement/catalog/${cwCatalogId}`,
      );
      return response.data;
    } catch {
      const fallback = await connectWiseApi.get(
        `/procurement/catalog/items/${cwCatalogId}`,
      );
      return fallback.data;
    }
  },
  fetch: async (id: string): Promise<CatalogItem> => {
    const numericId = Number(id);
    if (!Number.isFinite(numericId)) {
      const response = await connectWiseApi.get(
        `/procurement/catalog/items/${id}`,
      );
      return response.data;
    }

    return catalogCw.fetchByCatalogId(numericId);
  },
};
