// import { Autumn } from "@/external/autumn/autumnCli.js";
// import { setupBefore } from "tests/before.js";
// import { CusProductStatus, organizations } from "@autumn/shared";
// import { getFeaturePrice, getUsagePriceTiers } from "tests/utils/genUtils.js";
// import { entityProducts, features } from "../global.js";
// import { Stripe } from "stripe";
// import { checkBalance } from "tests/utils/autumnUtils.js";
// import { initCustomerWithTestClock } from "tests/utils/testInitUtils.js";
// import { advanceTestClock } from "tests/utils/stripeUtils.js";
// import { addDays, addHours, addMonths } from "date-fns";
// import { CacheManager } from "@/external/caching/CacheManager.js";
// import { CacheType } from "@/external/caching/cacheActions.js";
// import { hashApiKey } from "@/internal/dev/api-keys/apiKeyUtils.js";
// import { compareMainProduct } from "../utils/compare.js";
// import { assert, expect } from "chai";

// import chalk from "chalk";
// import { DrizzleCli } from "@/db/initDrizzle.js";
// import { CusProductService } from "@/internal/customers/cusProducts/CusProductService.js";
// import { eq } from "drizzle-orm";

// // Check balance and stripe quantity
// const checkEntAndStripeQuantity = async ({
//   db,
//   autumn,
//   stripeCli,
//   featureId,
//   customerId,
//   expectedBalance,
//   expectedUsage,
//   expectedStripeQuantity,
// }: {
//   db: DrizzleCli;
//   autumn: Autumn;
//   stripeCli: Stripe;
//   featureId: string;
//   customerId: string;
//   expectedBalance: number;
//   expectedUsage?: number;
//   expectedStripeQuantity: number;
// }) => {
//   let { customer, entitlements, products } =
//     await autumn.customers.get(customerId);

//   let cusProducts = await CusProductService.list({
//     db,
//     internalCustomerId: customer.internal_id,
//     inStatuses: [CusProductStatus.Active],
//   });

//   let entitlement = entitlements.find((e: any) => e.feature_id == featureId);

//   expect(entitlement.balance).to.equal(expectedBalance);
//   if (expectedUsage) {
//     expect(entitlement.used).to.equal(
//       expectedUsage,
//       `Get customer ${customerId} returned incorrect "used" for feature ${featureId}`,
//     );
//   }

//   if (products.length == 0) {
//     assert.fail(`Get customer ${customerId} returned no products`);
//   }

//   // 2. Get stripe quantity
//   let mainProduct = products[0];

//   if (mainProduct.subscription_ids.length == 0) {
//     assert.fail(`Get customer ${customerId} returned no subscriptions`);
//   }

//   let price = getFeaturePrice({
//     product: mainProduct,
//     featureId: featureId,
//     cusProducts,
//   });

//   if (!price) {
//     assert.fail(
//       `Get customer ${customerId} returned no price for feature ${featureId}`,
//     );
//   }

//   let stripeSub = await stripeCli.subscriptions.retrieve(
//     mainProduct.subscription_ids[0],
//   );
//   let subItem = stripeSub.items.data.find(
//     (item: any) => item.price.id == price.config!.stripe_price_id,
//   );

//   if (!subItem) {
//     assert.fail(
//       `Get customer ${customerId} returned no sub item for feature ${featureId}`,
//     );
//   }

//   expect(subItem.quantity).to.equal(
//     expectedStripeQuantity,
//     `Get customer ${customerId} returned incorrect stripe quantity for feature ${featureId}`,
//   );
// };

// // UNCOMMENT FROM HERE
// describe(`${chalk.yellowBright("entities1: Testing entities")}`, () => {
//   let customerId = "entity1";
//   let autumn: Autumn;
//   let stripeCli: Stripe;
//   let usageTiers = getUsagePriceTiers({
//     product: entityProducts.entityPro,
//     featureId: features.seats.id,
//   });
//   let testClockId: string;

//   before(async function () {
//     await setupBefore(this);
//     autumn = this.autumn;
//     stripeCli = this.stripeCli;

//     const { testClockId: testClockId1 } = await initCustomerWithTestClock({
//       customerId,
//       db: this.db,
//       org: this.org,
//       env: this.env,
//     });

//     testClockId = testClockId1;

//     // Update org config
//     await this.db
//       .update(organizations)
//       .set({
//         config: {
//           ...this.org.config,
//           prorate_unused: false,
//         },
//       })
//       .where(eq(organizations.id, this.org.id));

//     await CacheManager.invalidate({
//       action: CacheType.SecretKey,
//       value: hashApiKey(process.env.UNIT_TEST_AUTUMN_SECRET_KEY!),
//     });
//     await CacheManager.disconnect();
//   });

//   let firstEntityId = "1";

//   it("should attach entityFree product", async function () {
//     await this.autumn.attach({
//       customerId,
//       productId: entityProducts.entityFree.id,
//     });

//     await this.autumn.entities.create(customerId, {
//       id: firstEntityId,
//       name: "1@gmail.com",
//       featureId: features.seats.id,
//     });

//     // Check if entity is created
//     let res = await this.autumn.entities.list(customerId);
//     let entities = res.data;

//     expect(entities).to.have.lengthOf(1);
//     expect(entities[0].id).to.equal(firstEntityId);
//   });

//   it("should successfully remove created entity", async function () {
//     await this.autumn.entities.delete(customerId, firstEntityId);

//     let res = await this.autumn.entities.list(customerId);
//     let entities = res.data;
//     expect(entities).to.have.lengthOf(0);
//   });

//   it("should create first entity, then attach entityPro product", async function () {
//     await this.autumn.entities.create(customerId, {
//       id: firstEntityId,
//       name: "1@gmail.com",
//       featureId: features.seats.id,
//     });

//     await this.autumn.attach({
//       customerId,
//       productId: entityProducts.entityPro.id,
//     });

//     // Check product is attached correctly
//     let cusRes = await autumn.customers.get(customerId);
//     compareMainProduct({
//       sent: entityProducts.entityPro,
//       cusRes: cusRes,
//     });

//     let { invoices } = cusRes;
//     let usageTiers = getUsagePriceTiers({
//       product: entityProducts.entityPro,
//       featureId: features.seats.id,
//     });

//     // Check invoice is created correctly
//     expect(invoices).to.have.lengthOf(1);
//     expect(invoices[0].total).to.equal(usageTiers[0].amount);

//     // Check balance and stripe quantity
//     await checkEntAndStripeQuantity({
//       db: this.db,
//       autumn,
//       stripeCli,
//       featureId: features.seats.id,
//       customerId,
//       expectedBalance: -1,
//       expectedStripeQuantity: 1,
//     });

//     await checkBalance({
//       autumn,
//       featureId: features.metered1.id,
//       customerId,
//       expectedBalance:
//         entityProducts.entityPro.entitlements.metered1.allowance!,
//     });
//   });

//   let newEntities = [
//     {
//       id: "2",
//       name: "2@gmail.com",
//       featureId: features.seats.id,
//     },
//     {
//       id: "3",
//       name: "3@gmail.com",
//       featureId: features.seats.id,
//     },
//     {
//       id: "4",
//       name: "4@gmail.com",
//       featureId: features.seats.id,
//     },
//   ];

//   it("should create 3 additional entities and be charged immediately", async function () {
//     let advanceToDay = addDays(new Date(), 1).getTime();
//     await advanceTestClock({
//       stripeCli,
//       testClockId,
//       advanceTo: advanceToDay,
//       waitForSeconds: 20,
//     });

//     await this.autumn.entities.create(customerId, newEntities);

//     let entitiesRes = await this.autumn.entities.list(customerId);
//     let entities = entitiesRes.data;
//     expect(entities).to.have.lengthOf(newEntities.length + 1);

//     let cusRes = await autumn.customers.get(customerId);

//     let { invoices } = cusRes;
//     expect(invoices[0].total).to.equal(
//       usageTiers[0].amount * newEntities.length,
//     );
//   });

//   it("should remove 2 entities, and have correct balance / stripe quantity", async function () {
//     await this.autumn.entities.delete(customerId, newEntities[0].id);

//     await checkEntAndStripeQuantity({
//       db: this.db,
//       autumn,
//       stripeCli,
//       featureId: features.seats.id,
//       customerId,
//       expectedBalance: -(newEntities.length + 1),
//       expectedStripeQuantity: newEntities.length + 1 - 1,
//       expectedUsage: newEntities.length + 1 - 1,
//     });

//     await this.autumn.entities.delete(customerId, newEntities[1].id);
//     await checkEntAndStripeQuantity({
//       db: this.db,
//       autumn,
//       stripeCli,
//       featureId: features.seats.id,
//       customerId,
//       expectedBalance: -(newEntities.length + 1),
//       expectedStripeQuantity: newEntities.length + 1 - 2,
//       expectedUsage: newEntities.length + 1 - 2,
//     });
//   });

//   let newEntities2 = [
//     {
//       id: "5",
//       name: "5@gmail.com",
//       featureId: features.seats.id,
//     },
//     {
//       id: "6",
//       name: "6@gmail.com",
//       featureId: features.seats.id,
//     },
//     {
//       id: "7",
//       name: "7@gmail.com",
//       featureId: features.seats.id,
//     },
//   ];

//   it("should create three additional seats, and be charged for only one", async function () {
//     await this.autumn.entities.create(customerId, newEntities2);

//     let totalSeats = newEntities2.length + 2;
//     await checkEntAndStripeQuantity({
//       db: this.db,
//       autumn,
//       stripeCli,
//       featureId: features.seats.id,
//       customerId,
//       expectedBalance: -totalSeats,
//       expectedStripeQuantity: totalSeats,
//       expectedUsage: totalSeats,
//     });

//     let cusRes = await autumn.customers.get(customerId);
//     let { invoices } = cusRes;
//     expect(invoices[0].total).to.equal(usageTiers[0].amount);
//   });

//   // return;

//   it("should remove one entity, and have correct balance / stripe quantity after advancing test clock", async function () {
//     await this.autumn.entities.delete(customerId, newEntities2[0].id);

//     let totalSeats = newEntities2.length + 1;

//     let advanceTo = addHours(addMonths(new Date(), 1), 4).getTime();
//     await advanceTestClock({ stripeCli, testClockId, advanceTo });

//     // Get entities
//     let { data: entities } = await this.autumn.entities.list(customerId);
//     expect(entities).to.have.lengthOf(totalSeats);

//     await checkEntAndStripeQuantity({
//       db: this.db,
//       autumn,
//       stripeCli,
//       featureId: features.seats.id,
//       customerId,
//       expectedBalance: -totalSeats,
//       expectedStripeQuantity: totalSeats,
//       expectedUsage: totalSeats,
//     });

//     await checkBalance({
//       autumn,
//       featureId: features.metered1.id,
//       customerId,
//       expectedBalance:
//         totalSeats * entityProducts.entityPro.entitlements.metered1.allowance!,
//     });
//   });

//   after(async function () {
//     await this.db
//       .update(organizations)
//       .set({
//         config: {
//           ...this.org.config,
//           prorate_unused: true,
//         },
//       })
//       .where(eq(organizations.id, this.org.id));

//     void CacheManager.invalidate({
//       action: CacheType.SecretKey,
//       value: hashApiKey(process.env.UNIT_TEST_AUTUMN_SECRET_KEY!),
//     });
//   });
// });
