/**
 * One-shot migration: collapse the Approver table into the Admin table.
 *
 * What it does, per owner:
 *   1. For every Approver row, upsert a matching Admin (matched by email)
 *      with isApprover=true, canApproveRequests=true, and the approver's
 *      phone/designation/department/canAddVisitors carried over.
 *   2. Repoints Visitor.assignedApproverId → Visitor.assignedAdminId so the
 *      visitor still routes to the same human after future code drops the
 *      Approver table.
 *
 * Idempotent: re-running picks up new Approver rows without duplicating
 * Admin rows. Approver records are NOT deleted in this step — step 3 of the
 * refactor (route/UI rewire) will remove them once nothing reads from them.
 *
 * Run with: npx ts-node -r dotenv/config src/scripts/mergeApproversIntoAdmins.ts
 */

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

async function main(): Promise<void> {
  const approvers = await prisma.approver.findMany({ orderBy: { createdAt: 'asc' } });
  console.log(`[merge] ${approvers.length} approver rows to migrate`);

  // ─── 1. Approver → Admin upserts ────────────────────────────────────────
  // emailToAdminId lets us repoint visitor FKs in step 2 without re-querying.
  const emailToAdminId: Record<string, string> = {};

  for (const a of approvers) {
    const existing = await prisma.admin.findUnique({ where: { email: a.email } });

    if (existing) {
      // Member is already an admin — just turn on the approver flag and
      // backfill any approver-only metadata we don't already have.
      const updated = await prisma.admin.update({
        where: { id: existing.id },
        data: {
          isApprover: true,
          canApproveRequests: existing.canApproveRequests || true,
          phone: existing.phone ?? a.phone,
          designation: existing.designation ?? a.designation,
          department: existing.department ?? a.department,
          canAddVisitors: existing.canAddVisitors || a.canAddVisitors,
        },
      });
      emailToAdminId[a.email] = updated.id;
      console.log(`[merge] ${a.email}: upgraded existing admin → isApprover`);
    } else {
      const created = await prisma.admin.create({
        data: {
          ownerId: a.ownerId,
          name: a.name,
          email: a.email,
          phone: a.phone,
          designation: a.designation,
          department: a.department,
          isActive: a.isActive,
          isApprover: true,
          // Approvers historically didn't get sub-admin manage permissions.
          // Defaults keep them scoped to their own queue.
          canManageVisitors: false,
          canManageApprovers: false,
          canManageSettings: false,
          canApproveRequests: true,
          canAddVisitors: a.canAddVisitors,
        },
      });
      emailToAdminId[a.email] = created.id;
      console.log(`[merge] ${a.email}: created admin row`);
    }
  }

  // ─── 2. Repoint Visitor.assignedApproverId → assignedAdminId ────────────
  const visitors = await prisma.visitor.findMany({
    where: { assignedApproverId: { not: null }, assignedAdminId: null },
    select: { id: true, assignedApproverId: true, assignedApprover: { select: { email: true } } },
  });
  console.log(`[merge] ${visitors.length} visitor rows to repoint`);

  let repointed = 0;
  for (const v of visitors) {
    const email = v.assignedApprover?.email;
    const adminId = email ? emailToAdminId[email] : null;
    if (!adminId) continue;
    await prisma.visitor.update({
      where: { id: v.id },
      data: { assignedAdminId: adminId },
    });
    repointed += 1;
  }
  console.log(`[merge] repointed ${repointed} visitors`);

  console.log('[merge] done — Approver rows preserved, step 3 will drop them.');
}

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