/**
 * Delete all visitor data for a specific owner (matched by email).
 *
 * Usage:
 *   ts-node -r dotenv/config src/scripts/delete-owner-visitors.ts <email>             # dry-run
 *   ts-node -r dotenv/config src/scripts/delete-owner-visitors.ts <email> --confirm   # actually delete
 *
 * What "all visitor data" means:
 *   - Visitor rows owned by this owner (every visitor in their workspace)
 *   - VisitorScanLog rows for those visitors
 *   - VisitorRequest rows owned by this owner (walk-ins, which may reference
 *     a Visitor row via visitorId)
 *
 * What this DOES NOT touch:
 *   - The Owner row itself (login + workspace stays alive)
 *   - Admins, Approvers, Checkpoints, Departments, Reasons, EmailTemplates
 *   - Any other owner's data
 *
 * All deletes happen inside a single transaction. If anything fails, nothing
 * is removed.
 */

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-owner-visitors.ts <email> [--confirm]');
    process.exit(1);
  }

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

  console.log(`Owner: ${owner.email} (id=${owner.id}, name=${owner.name ?? '—'})`);

  // Count first so the dry-run output makes sense.
  const visitorRows = await prisma.visitor.findMany({
    where: { ownerId: owner.id },
    select: { id: true, shortId: true },
  });
  const ids = visitorRows.map((v) => v.id);
  const shortIds = visitorRows.map((v) => v.shortId);

  const [scanLogCount, walkInCount, notifCount] = await Promise.all([
    prisma.visitorScanLog.count({ where: { visitorId: { in: ids } } }),
    prisma.visitorRequest.count({ where: { ownerId: owner.id } }),
    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(`  ${scanLogCount} VisitorScanLog row(s)`);
  console.log(`  ${walkInCount} VisitorRequest row(s) (walk-ins for this workspace)`);
  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;
  }

  console.log('\n--confirm passed. Deleting…');

  // FK order:
  //   1. VisitorScanLog (FK → Visitor)
  //   2. VisitorRequest (may FK → Visitor via visitorId, and owns its own row)
  //   3. Visitor
  //   4. Notification rows referencing these visitors' shortIds (no FK,
  //      matched by body containing `#<shortId>`)
  const result = await prisma.$transaction(async (tx) => {
    const logs = await tx.visitorScanLog.deleteMany({ where: { visitorId: { in: ids } } });
    const requests = await tx.visitorRequest.deleteMany({ where: { ownerId: owner.id } });
    const visitors = await tx.visitor.deleteMany({ where: { ownerId: owner.id } });
    const notifications = shortIds.length === 0
      ? { count: 0 }
      : await tx.notification.deleteMany({
          where: {
            type: { startsWith: 'visitor.' },
            OR: shortIds.map((s) => ({ body: { contains: `#${s}` } })),
          },
        });
    return {
      logs: logs.count,
      requests: requests.count,
      visitors: visitors.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());
