import { and, eq, inArray, or } from "drizzle-orm";

import { db } from "./index";
import {
  walletPaymentIntentsTable,
  walletsTable,
  walletTransactionsTable,
} from "./schema";

const SUSU_WALLET_OWNER_ID = 1;

async function main() {
  const existingSusuWallets = await db
    .select()
    .from(walletsTable)
    .where(
      and(
        eq(walletsTable.ownerType, "SUSU" as any),
        eq(walletsTable.ownerId, SUSU_WALLET_OWNER_ID),
      ),
    );

  const susuWallet =
    existingSusuWallets[0] ??
    (
      await db
        .insert(walletsTable)
        .values({
          ownerType: "SUSU" as any,
          ownerId: SUSU_WALLET_OWNER_ID,
        })
        .returning()
    )[0];

  const circleWallets = await db
    .select()
    .from(walletsTable)
    .where(eq(walletsTable.ownerType, "CIRCLE" as any));

  if (circleWallets.length === 0) {
    console.log("No legacy circle wallets found. SUSU wallet is ready.");
    return;
  }

  const circleWalletIds = circleWallets.map((wallet) => wallet.id);
  console.log(
    `Found ${circleWalletIds.length} legacy circle wallet(s). Migrating into SUSU wallet #${susuWallet.id}...`,
  );

  const creditResult = await db
    .update(walletTransactionsTable)
    .set({ toWalletId: susuWallet.id } as any)
    .where(inArray(walletTransactionsTable.toWalletId, circleWalletIds));

  const debitResult = await db
    .update(walletTransactionsTable)
    .set({ fromWalletId: susuWallet.id } as any)
    .where(inArray(walletTransactionsTable.fromWalletId, circleWalletIds));

  const lingeringTransactions = await db
    .select({ id: walletTransactionsTable.id })
    .from(walletTransactionsTable)
    .where(
      or(
        inArray(walletTransactionsTable.toWalletId, circleWalletIds),
        inArray(walletTransactionsTable.fromWalletId, circleWalletIds),
      ) as any,
    );

  const lingeringIntents = await db
    .select({ id: walletPaymentIntentsTable.id, walletId: walletPaymentIntentsTable.walletId })
    .from(walletPaymentIntentsTable)
    .where(inArray(walletPaymentIntentsTable.walletId, circleWalletIds));

  if (lingeringTransactions.length === 0 && lingeringIntents.length === 0) {
    await db.delete(walletsTable).where(inArray(walletsTable.id, circleWalletIds));
    console.log(`Deleted ${circleWalletIds.length} legacy circle wallet row(s).`);
  } else {
    console.log(
      `Skipped deleting legacy circle wallets. Remaining tx refs: ${lingeringTransactions.length}, intent refs: ${lingeringIntents.length}.`,
    );
  }

  console.log("SUSU wallet migration complete.", {
    updatedCredits: creditResult.rowCount ?? 0,
    updatedDebits: debitResult.rowCount ?? 0,
    susuWalletId: susuWallet.id,
  });
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error("Failed to migrate SUSU wallet data.", error);
    process.exit(1);
  });
