/**
 * Dev-only: wipe all application data while keeping catalog / reference tables from seed.
 *
 * Preserved: organization_types, plans, features, permissions, treatment_types,
 * lab_workflow_steps, prosthesis_types, prosthesis_type_steps, catalog_translations
 *
 * Usage: npm run prisma:wipe-app-data
 */
import { PrismaClient } from '@prisma/client';
import { config } from 'dotenv';
import { existsSync, rmSync } from 'fs';
import path from 'path';

const envPath = path.join(__dirname, '..', '.env');
config({ path: envPath });

if (process.env.NODE_ENV === 'production') {
  console.error('wipe-app-data is not allowed in production');
  process.exit(1);
}

const prisma = new PrismaClient();

const CATALOG_TABLES = new Set([
  'organization_types',
  'plans',
  'features',
  'permissions',
  'treatment_types',
  'lab_workflow_steps',
  'prosthesis_types',
  'prosthesis_type_steps',
  'catalog_translations',
]);

// FK-safe order: children before parents where CASCADE is not enough.
const TABLES_IN_ORDER = [
  'phone_verification_codes',
  'staff_working_hours_blocks',
  'staff_working_hours_schedules',
  'staff_invitations',
  'membership_permissions',
  'sessions',
  'user_notifications',
  'lab_case_user_read_states',
  'lab_case_user_tab_read_states',
  'lab_case_task_status_events',
  'lab_case_comments',
  'lab_case_attachments',
  'lab_case_tasks',
  'lab_case_sends',
  'lab_case_tooth_prosthesis',
  'lab_case_details',
  'lab_cases',
  'lab_case_activities',
  'treatment_detail_attachments',
  'treatment_details',
  'treatments',
  'appointments',
  'organization_links',
  'organization_invitations',
  'patients',
  'memberships',
  'organizations',
  'users',
];

async function tableExists(table: string): Promise<boolean> {
  const rows = await prisma.$queryRawUnsafe<Array<{ exists: string | null }>>(
    `SELECT to_regclass('public."${table}"')::text AS exists`,
  );
  return rows[0]?.exists != null;
}

async function main() {
  console.log('🧹 Wiping application data (keeping catalog / reference tables)...');

  const existing: string[] = [];
  for (const table of TABLES_IN_ORDER) {
    if (CATALOG_TABLES.has(table)) {
      throw new Error(`Misconfigured wipe list includes catalog table: ${table}`);
    }
    if (await tableExists(table)) {
      existing.push(table);
    } else {
      console.log(`  - skipping "${table}" (does not exist yet)`);
    }
  }

  if (existing.length === 0) {
    console.log('No application tables found. Run `prisma migrate deploy` first.');
    return;
  }

  const targets = existing.map((t) => `"${t}"`).join(', ');
  await prisma.$executeRawUnsafe(`TRUNCATE TABLE ${targets} RESTART IDENTITY CASCADE`);

  const uploadRoot = path.join(__dirname, '..', 'uploads');
  if (existsSync(uploadRoot)) {
    rmSync(uploadRoot, { recursive: true, force: true });
    console.log('  - removed local uploads/ directory');
  }

  console.log('✅ Application data wiped.');
  console.log('   Preserved catalog tables:', [...CATALOG_TABLES].sort().join(', '));
  console.log('   Register a new user / org to start fresh testing.');
}

main()
  .catch((e) => {
    console.error('❌ Wipe failed:', e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });
