/**
 * One-shot: remove leaked test data from dev DB.
 *
 * Test runs that crashed before reaching `afterAll` left orphan test users +
 * programs. This mirrors `tests/helpers.ts#cleanupTestData` with the same
 * reverse-dependency order, applied to all programs whose name matches the
 * test patterns.
 *
 * Run: npx tsx scripts/cleanup-test-pollution.ts
 */
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

const TEST_PROGRAM_PATTERNS = [
  'Test Program prog-%',
  'getCandidates-%',
  'bulk-%',
  'source-flag-%',
  'mentor-files-%',
  'mentor-config-%',
]

async function main() {
  const programs = await prisma.program.findMany({
    where: {
      OR: TEST_PROGRAM_PATTERNS.map((p) => ({ name: { startsWith: p.replace('%', '') } })),
    },
    select: { id: true, name: true },
  })

  console.log(`Found ${programs.length} test programs:`)
  programs.forEach((p) => console.log(`  - ${p.id}  ${p.name}`))

  for (const program of programs) {
    const programId = program.id
    console.log(`\nCleaning ${program.name}...`)

    // MentorAssignment isn't in cleanupTestData — kill it first
    const ma = await prisma.mentorAssignment.deleteMany({
      where: { project: { programId } },
    })
    if (ma.count > 0) console.log(`  ${ma.count} MentorAssignment`)

    // Mirror tests/helpers.ts#cleanupTestData order
    await prisma.cohortProject.deleteMany({ where: { cohort: { round: { competition: { programId } } } } })
    await prisma.cohort.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.liveProgressCursor.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.filteringResult.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.filteringRule.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.filteringJob.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.assignmentJob.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.conflictOfInterest.deleteMany({ where: { assignment: { round: { competition: { programId } } } } })
    await prisma.evaluation.deleteMany({ where: { assignment: { round: { competition: { programId } } } } })
    await prisma.assignment.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.evaluationForm.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.fileRequirement.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.gracePeriod.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.reminderLog.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.evaluationSummary.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.evaluationDiscussion.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.projectRoundState.deleteMany({ where: { round: { competition: { programId } } } })
    await prisma.awardEligibility.deleteMany({ where: { award: { program: { id: programId } } } })
    await prisma.awardVote.deleteMany({ where: { award: { program: { id: programId } } } })
    await prisma.awardJuror.deleteMany({ where: { award: { program: { id: programId } } } })
    await prisma.specialAward.deleteMany({ where: { programId } })
    await prisma.round.deleteMany({ where: { competition: { programId } } })
    await prisma.competition.deleteMany({ where: { programId } })
    await prisma.projectStatusHistory.deleteMany({ where: { project: { programId } } })
    await prisma.projectFile.deleteMany({ where: { project: { programId } } })
    await prisma.projectTag.deleteMany({ where: { project: { programId } } })
    await prisma.project.deleteMany({ where: { programId } })
    await prisma.program.deleteMany({ where: { id: programId } })
    console.log('  cascade complete')
  }

  // Delete test users (@test.local). Catch any audit-log refs first.
  const testUsers = await prisma.user.findMany({
    where: { email: { endsWith: '@test.local' } },
    select: { id: true },
  })
  const testUserIds = testUsers.map((u) => u.id)
  console.log(`\nDeleting ${testUserIds.length} @test.local users...`)
  if (testUserIds.length > 0) {
    await prisma.decisionAuditLog.deleteMany({ where: { actorId: { in: testUserIds } } })
    await prisma.auditLog.deleteMany({ where: { userId: { in: testUserIds } } })
    // Any remaining MentorAssignments referencing these users (e.g., from other tests)
    await prisma.mentorAssignment.deleteMany({ where: { mentorId: { in: testUserIds } } })
    await prisma.user.deleteMany({ where: { id: { in: testUserIds } } })
  }

  console.log('\nDone.')
}

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