/**
 * One-time backfill script to populate category/subcategory fields
 * on existing CatalogItem records from ConnectWise data.
 *
 * Usage: bun utils/backfillCatalogCategories.ts
 */
import { prisma, connectWiseApi } from "../src/constants";

interface CWReference {
  id: number;
  name: string;
}

interface CatalogItemPartial {
  id: number;
  category: CWReference;
  subcategory: CWReference;
}

async function main() {
  // 1. Find all DB items that are missing category data
  const dbItems = await prisma.catalogItem.findMany({
    where: { category: null },
    select: { cwCatalogId: true, id: true },
  });

  if (dbItems.length === 0) {
    console.log("All catalog items already have category data. Nothing to do.");
    return;
  }

  console.log(`Found ${dbItems.length} catalog items missing category data.`);

  // 2. Fetch all items from CW with category/subcategory fields
  const pageSize = 1000;
  const countRes = await connectWiseApi.get("/procurement/catalog/count");
  const totalCount = countRes.data.count;
  const totalPages = Math.ceil(totalCount / pageSize);

  const cwMap = new Map<
    number,
    { category: CWReference; subcategory: CWReference }
  >();

  for (let page = 1; page <= totalPages; page++) {
    const res = await connectWiseApi.get(
      `/procurement/catalog?page=${page}&pageSize=${pageSize}&fields=id,category,subcategory`,
    );
    const items: CatalogItemPartial[] = res.data;
    for (const item of items) {
      cwMap.set(item.id, {
        category: item.category,
        subcategory: item.subcategory,
      });
    }
  }

  console.log(`Fetched ${cwMap.size} items from CW. Updating DB...`);

  // 3. Batch update
  let updated = 0;
  const batchSize = 50;

  for (let i = 0; i < dbItems.length; i += batchSize) {
    const batch = dbItems.slice(i, i + batchSize);
    await Promise.all(
      batch.map(async (dbItem) => {
        const cwData = cwMap.get(dbItem.cwCatalogId);
        if (!cwData) return;

        await prisma.catalogItem.update({
          where: { id: dbItem.id },
          data: {
            category: cwData.category?.name ?? null,
            categoryCwId: cwData.category?.id ?? null,
            subcategory: cwData.subcategory?.name ?? null,
            subcategoryCwId: cwData.subcategory?.id ?? null,
          },
        });
        updated++;
      }),
    );
    console.log(
      `  Updated ${Math.min(i + batchSize, dbItems.length)}/${dbItems.length}...`,
    );
  }

  console.log(`Done. Updated ${updated} catalog items with category data.`);
}

main()
  .catch(console.error)
  .finally(() => prisma.$disconnect());
