/**
 * Delete every Visitor row tied to a specific sub-admin (matched by email),
 * either as the creator (`createdByAdminId`) OR the assignee (`assignedAdminId`).
 *
 * Usage:
 *   ts-node -r dotenv/config src/scripts/delete-admin-visitors.ts <email>             # dry-run
 *   ts-node -r dotenv/config src/scripts/delete-admin-visitors.ts <email> --confirm   # apply
 *
 * Cascade order:
 *   1. VisitorScanLog (FK → Visitor)
 *   2. VisitorRequest (FK → Visitor via visitorId — walk-ins backed by these visitors)
 *   3. Visitor
 *
 * What this DOES NOT touch:
 *   - The Admin row itself (their login + assignments stay)
 *   - The AllowedEmail row
 *   - Any visitor NOT created-by or assigned-to this admin
 *   - VisitorRequest rows whose visitorId is NULL or points to other visitors
 *
 * Everything runs inside a transaction.
 */

import { prisma } from '../config/database';

async function main() {
  const email = process.argv[2];
  const confirm = process.argv.includes('--confirm');

  if (!email) {
    console.error('Usage: ts-node src/scripts/delete-admin-visitors.ts <email> [--confirm]');
    process.exit(1);
  }

  const admin = await prisma.admin.findUnique({ where: { email } });
  if (!admin) {
    console.error(`No Admin found for email: ${email}`);
    process.exit(1);
  }

  console.log(`Admin: ${admin.email} (id=${admin.id}, ownerId=${admin.ownerId}, name=${admin.name})`);

  const visitors = await prisma.visitor.findMany({
    where: {
      OR: [
        { createdByAdminId: admin.id },
        { assignedAdminId: admin.id },
      ],
    },
    select: { id: true, shortId: true, createdByAdminId: true, assignedAdminId: true },
  });
  const ids = visitors.map((v) => v.id);
  const shortIds = visitors.map((v) => v.shortId);
  const createdCount = visitors.filter((v) => v.createdByAdminId === admin.id).length;
  const assignedCount = visitors.filter((v) => v.assignedAdminId === admin.id).length;
  const bothCount = visitors.filter(
    (v) => v.createdByAdminId === admin.id && v.assignedAdminId === admin.id,
  ).length;

  const [scanLogCount, walkInCount, notifCount] = await Promise.all([
    prisma.visitorScanLog.count({ where: { visitorId: { in: ids } } }),
    prisma.visitorRequest.count({ where: { visitorId: { in: ids } } }),
    shortIds.length === 0
      ? Promise.resolve(0)
      : prisma.notification.count({
          where: {
            type: { startsWith: 'visitor.' },
            OR: shortIds.map((s) => ({ body: { contains: `#${s}` } })),
          },
        }),
  ]);

  console.log('\nWill delete:');
  console.log(`  ${ids.length} Visitor row(s)`);
  console.log(`     ↳ ${createdCount} created by this admin`);
  console.log(`     ↳ ${assignedCount} assigned to this admin`);
  console.log(`     ↳ ${bothCount} both created AND assigned (counted once)`);
  console.log(`  ${scanLogCount} VisitorScanLog row(s)`);
  console.log(`  ${walkInCount} VisitorRequest row(s) (walk-ins backed by these visitors)`);
  console.log(`  ${notifCount} Notification row(s) referencing these visitors' shortIds`);

  if (!confirm) {
    console.log('\nDry run — nothing deleted. Re-run with --confirm to apply.');
    return;
  }

  if (ids.length === 0) {
    console.log('\nNothing to delete.');
    return;
  }

  console.log('\n--confirm passed. Deleting…');
  const result = await prisma.$transaction(async (tx) => {
    const logs = await tx.visitorScanLog.deleteMany({ where: { visitorId: { in: ids } } });
    const requests = await tx.visitorRequest.deleteMany({ where: { visitorId: { in: ids } } });
    const deletedVisitors = await tx.visitor.deleteMany({ where: { id: { in: ids } } });
    const notifications = await tx.notification.deleteMany({
      where: {
        type: { startsWith: 'visitor.' },
        OR: shortIds.map((s) => ({ body: { contains: `#${s}` } })),
      },
    });
    return {
      logs: logs.count,
      requests: requests.count,
      visitors: deletedVisitors.count,
      notifications: notifications.count,
    };
  });

  console.log('\nDeleted:');
  console.log(`  ${result.visitors} Visitor row(s)`);
  console.log(`  ${result.logs} VisitorScanLog row(s)`);
  console.log(`  ${result.requests} VisitorRequest row(s)`);
  console.log(`  ${result.notifications} Notification row(s)`);
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(() => prisma.$disconnect());
