// // src/scripts/import-employees-from-csv.ts
// import { PrismaClient, Roles } from '@prisma/client';
// import * as fs from 'fs';
// import * as path from 'path';

// const prisma = new PrismaClient();

// // Chemin vers ton CSV employees
// const CSV_PATH = path.resolve(__dirname, 'data/export_new_employee_table.csv');

// // Rôles éligibles pour la table Employees
// const ELIGIBLE_ROLES: Roles[] = [
//   Roles.EMPLOYEE,
//   Roles.SUPERVISOR,
//   Roles.HR,
//   Roles.ACCOUNTING,
//   Roles.ADMIN,
// ];

// // Type correspondant EXACT aux colonnes de ton CSV
// type EmployeeCsvRow = {
//   employee_number: string;
//   email: string;
//   job_title: string;
//   company: string;       // sera converti en number
//   is_supervisor: string; // "True"/"False" (ou variantes)
//   onboarding: string;    // millis
//   offboarding: string;   // millis ou "NULL"
// };

// // Représentation minimale d'un user
// type UserSummary = {
//   id: string;   // UUID
//   email: string;
//   role: Roles;
// };

// // ============ Helpers CSV ============

// function splitCsvLine(line: string): string[] {
//   const result: string[] = [];
//   let current = '';
//   let inQuotes = false;

//   for (let i = 0; i < line.length; i++) {
//     const char = line[i];

//     if (char === '"') {
//       // guillemet échappé ""
//       if (inQuotes && line[i + 1] === '"') {
//         current += '"';
//         i++;
//       } else {
//         inQuotes = !inQuotes;
//       }
//     } else if (char === ',' && !inQuotes) {
//       result.push(current);
//       current = '';
//     } else {
//       current += char;
//     }
//   }

//   result.push(current);
//   return result.map((v) => v.trim());
// }

// // ============ Helpers de parsing ============

// function parseBoolean(value: string): boolean {
//   const v = value.trim().toLowerCase();
//   return v === 'true' || v === '1' || v === 'yes' || v === 'y' || v === 'oui';
// }

// function parseIntSafe(value: string, fieldName: string): number | null {
//   const trimmed = value.trim();
//   if (!trimmed || trimmed.toUpperCase() === 'NULL') return null;

//   const n = Number.parseInt(trimmed, 10);
//   if (Number.isNaN(n)) {
//     console.warn(` Impossible de parser "${value}" en entier pour le champ ${fieldName}`);
//     return null;
//   }
//   return n;
// }

// function millisToDate(value: string): Date | null {
//   const trimmed = value.trim().toUpperCase();
//   if (!trimmed || trimmed === 'NULL') return null;

//   const ms = Number(trimmed);
//   if (!Number.isFinite(ms)) {
//     console.warn(` Impossible de parser "${value}" en millis pour une Date`);
//     return null;
//   }

//   const d = new Date(ms);
//   // On normalise au jour (minuit UTC)
//   const normalized = new Date(Date.UTC(
//     d.getUTCFullYear(),
//     d.getUTCMonth(),
//     d.getUTCDate(),
//   ));

//   return normalized;
// }

// // ============ MAIN ============

// async function main() {
//   // 1. Lecture du CSV
//   const fileContent = fs.readFileSync(CSV_PATH, 'utf-8');

//   const lines = fileContent
//     .split(/\r?\n/)
//     .map((l) => l.trim())
//     .filter((l) => l.length > 0);

//   if (lines.length <= 1) {
//     console.error('CSV vide ou seulement un header');
//     return;
//   }

//   const header = splitCsvLine(lines[0]); // ["employee_number","email",...]
//   const dataLines = lines.slice(1);

//   const csvRows: EmployeeCsvRow[] = dataLines.map((line) => {
//     const values = splitCsvLine(line);
//     const row: any = {};

//     header.forEach((col, idx) => {
//       row[col] = values[idx] ?? '';
//     });

//     return row as EmployeeCsvRow;
//   });

//   console.log(` ${csvRows.length} lignes trouvées dans le CSV employees`);

//   // 2. Récupérer tous les emails du CSV
//   const emails = Array.from(
//     new Set(
//       csvRows
//         .map((r) => r.email.trim())
//         .filter((e) => e.length > 0),
//     ),
//   );

//   console.log(` ${emails.length} emails uniques trouvés dans le CSV`);

//   // 3. Charger les users correspondants avec les bons rôles
//   const users = (await prisma.users.findMany({
//     where: {
//       email: { in: emails },
//       role: { in: ELIGIBLE_ROLES },
//     },
//     select: {
//       id: true,
//       email: true,
//       role: true,
//     },
//   })) as UserSummary[];

//   console.log(` ${users.length} users éligibles trouvés dans la DB`);

//   // Map email → user
//   const userByEmail = new Map<string, UserSummary>();
//   for (const user of users) {
//     const key = user.email.trim().toLowerCase();
//     userByEmail.set(key, user);
//   }

//   // 4. Construire les données pour employees.createMany
//   const employeesToCreate: {
//     user_id: string;
//     external_payroll_id: number;
//     company_code: number;
//     first_work_day: Date;
//     last_work_day: Date | null;
//     job_title: string | null;
//     is_supervisor: boolean;
//     supervisor_id?: number | null;
//     daily_expected_hours: number;
//   }[] = [];

//   const rowsWithoutUser: EmployeeCsvRow[] = [];
//   const rowsWithInvalidNumbers: EmployeeCsvRow[] = [];

//   for (const row of csvRows) {
//     const emailKey = row.email.trim().toLowerCase();
//     const user = userByEmail.get(emailKey);

//     if (!user) {
//       rowsWithoutUser.push(row);
//       continue;
//     }

//     const external_payroll_id = parseIntSafe(row.employee_number, 'external_payroll_id');
//     const company_code = parseIntSafe(String(row.company), 'company_code');

//     if (external_payroll_id === null || company_code === null) {
//       rowsWithInvalidNumbers.push(row);
//       continue;
//     }

//     const first_work_day = millisToDate(row.onboarding);
//     const last_work_day = millisToDate(row.offboarding);
//     const is_supervisor = parseBoolean(row.is_supervisor);
//     const job_title = row.job_title?.trim() || null;

//     if (!first_work_day) {
//       console.warn(
//         `WARNING: Date d'onboarding invalide pour ${row.email} (employee_number=${row.employee_number})`,
//       );
//       continue;
//     }

//     employeesToCreate.push({
//       user_id: user.id,
//       external_payroll_id,
//       company_code,
//       first_work_day,
//       last_work_day,
//       daily_expected_hours: 8,
//       job_title,
//       is_supervisor,
//       supervisor_id: null, // on pourra gérer ça plus tard si tu as les infos
//     });
//   }

//   console.log(` ${employeesToCreate.length} entrées Employees prêtes à être insérées`);

//   if (rowsWithoutUser.length > 0) {
//     console.warn(` ${rowsWithoutUser.length} lignes CSV sans user correspondant (email / rôle) :`);
//     for (const row of rowsWithoutUser) {
//       console.warn(
//         `  - email=${row.email}, employee_number=${row.employee_number}, company=${row.company}`,
//       );
//     }
//   }

//   if (rowsWithInvalidNumbers.length > 0) {
//     console.warn(` ${rowsWithInvalidNumbers.length} lignes CSV avec ids/compagnies invalides :`);
//     for (const row of rowsWithInvalidNumbers) {
//       console.warn(
//         `  - email=${row.email}, employee_number="${row.employee_number}", company="${row.company}"`,
//       );
//     }
//   }

//   if (employeesToCreate.length === 0) {
//     console.warn(' Aucun Employees à créer, arrêt.');
//     return;
//   }

//   // 5. Insert en batch
//   const result = await prisma.employees.createMany({
//     data: employeesToCreate,
//     skipDuplicates: true, // évite les erreurs si tu relances le script
//   });

//   console.log(` ${result.count} employees insérés dans la DB`);
// }

// main()
//   .catch((err) => {
//     console.error(' Erreur pendant l’import CSV → Employees', err);
//     process.exit(1);
//   })
//   .finally(async () => {
//     await prisma.$disconnect();
//   });
