// This script is responsible for synchronizing employee data from the local
// Prisma database to an external database. It is designed to be run as a scheduled task.

// --- External Database Configuration (PLACEHOLDERS - User MUST Configure via environment variables) ---
// IMPORTANT: These variables define the connection to your external database.
// You MUST configure these, ideally through environment variables, for the script to work.
// The script provides a template for different database types, but you'll need to:
// 1. Install the appropriate database client library (e.g., `npm install pg` or `npm install mysql2`).
// 2. Implement the actual database connection and query logic in the designated section.

const EXTERNAL_DB_TYPE = process.env.EXTERNAL_DB_TYPE || 'your_db_type_here'; // e.g., 'postgres', 'mysql'. User must set this.
const EXTERNAL_DB_HOST = process.env.EXTERNAL_DB_HOST || 'YOUR_EXTERNAL_DB_HOST'; // User must set this.
const EXTERNAL_DB_PORT = process.env.EXTERNAL_DB_PORT || 5432; // Adjust default port if needed. User must set this.
const EXTERNAL_DB_USER = process.env.EXTERNAL_DB_USER || 'YOUR_EXTERNAL_DB_USER'; // User must set this.
const EXTERNAL_DB_PASSWORD = process.env.EXTERNAL_DB_PASSWORD || 'YOUR_EXTERNAL_DB_PASSWORD'; // User must set this.
const EXTERNAL_DB_NAME = process.env.EXTERNAL_DB_NAME || 'YOUR_EXTERNAL_DB_NAME'; // User must set this.
const EXTERNAL_DB_EMPLEADOS_TABLE = process.env.EXTERNAL_DB_EMPLEADOS_TABLE || 'empleados_externos'; // User must set this.
// --- End of External Database Configuration ---

import { PrismaClient } from '../api/prisma/generated/client';
const prisma = new PrismaClient();

async function syncEmpleadosToExternalDB() {
  console.log('[SyncEmpleados] Starting synchronization process...');
  // Core logic for synchronization, wrapped in try/catch/finally to ensure
  // resources like the Prisma client are properly managed (e.g., disconnected).
  try {
    // Fetch all 'Cliente' records from the local Prisma database that are marked as 'empleado'.
    const localEmpleados = await prisma.cliente.findMany({
      where: { empleado: true }, // Filters for clients who are also employees
      select: {
        id: true, // Local ID, might be useful for logging/tracing
        name: true,
        cedula: true,
        ubicacion: true,
        telefono: true,
        // avatar_url: true, // Add other relevant fields
        // idciat: true, // Add other relevant fields
      },
    });

    if (!localEmpleados.length) {
      console.log('[SyncEmpleados] No employees found in local database. Nothing to sync.');
      return;
    }
    console.log(`[SyncEmpleados] Found ${localEmpleados.length} employees to sync.`);

    // --- External DB Connection Logic (User to implement based on EXTERNAL_DB_TYPE) ---
    // User must implement the actual database connection logic here based on EXTERNAL_DB_TYPE
    // and install the required database client library (e.g., 'pg' for PostgreSQL, 'mysql2' for MySQL).
    // The following are conceptual examples.

    // Example for PostgreSQL using 'pg' library (user would need to install it: npm install pg)
    /*
    if (EXTERNAL_DB_TYPE === 'postgres') {
      // const { Client } = require('pg'); // User would uncomment and install
      // const externalDbClient = new Client({
      //   host: EXTERNAL_DB_HOST,
      //   port: EXTERNAL_DB_PORT,
      //   user: EXTERNAL_DB_USER,
      //   password: EXTERNAL_DB_PASSWORD,
      //   database: EXTERNAL_DB_NAME,
      // });
      // await externalDbClient.connect();
      // console.log('[SyncEmpleados] Connected to external PostgreSQL database.');

      // ... (sync logic using externalDbClient) ...

      // await externalDbClient.end();
      // console.log('[SyncEmpleados] Disconnected from external PostgreSQL database.');
    } else if (EXTERNAL_DB_TYPE === 'mysql') {
      // const mysql = require('mysql2/promise'); // User would uncomment and install
      // const connection = await mysql.createConnection({
      //    host: EXTERNAL_DB_HOST,
      //    user: EXTERNAL_DB_USER,
      //    password: EXTERNAL_DB_PASSWORD,
      //    database: EXTERNAL_DB_NAME,
      //    port: EXTERNAL_DB_PORT,
      // });
      // console.log('[SyncEmpleados] Connected to external MySQL database.');

      // ... (sync logic using connection) ...

      // await connection.end();
      // console.log('[SyncEmpleados] Disconnected from external MySQL database.');
    } else {
      console.error(`[SyncEmpleados] Unsupported EXTERNAL_DB_TYPE: ${EXTERNAL_DB_TYPE}. User needs to implement connection logic.`);
      // For now, we will just log the data that would be synced
    }
    */
    // --- End of External DB Connection Logic ---

    console.log('[SyncEmpleados] --- Data to be Synced (Conceptual) ---');
    for (const emp of localEmpleados) {
      console.log(`[SyncEmpleados] Processing employee: ID=${emp.id}, Cedula=${emp.cedula}, Name=${emp.name}`);

      // Conceptual Upsert Logic: The following section outlines where you would implement the upsert (update or insert) operation.
      // You'll need to use your chosen external database client to first check if an employee
      // with a matching unique identifier (e.g., emp.cedula) exists in the ${EXTERNAL_DB_EMPLEADOS_TABLE}.
      // If it exists, execute an UPDATE statement. If not, execute an INSERT statement.
      // Ensure you map fields from 'emp' (local employee) to the corresponding columns in your external table.

      // Example of data to be inserted/updated:
      const externalData = {
        // Assuming external table has these columns. User must map accordingly.
        // Ensure data types are compatible between local and external databases.
        cedula: emp.cedula, // Primary key for matching in the external table (assumed)
        nombre: emp.name,
        telefono: emp.telefono,
        ubicacion: emp.ubicacion,
        // local_id: emp.id, // Optional: store local ID for reference
        // ... map other fields ...
      };
      console.log(`[SyncEmpleados] Data for external table: ${JSON.stringify(externalData)}`);
    }
    console.log('[SyncEmpleados] --- End of Data to be Synced ---');

  } catch (error) {
    // Catch any errors that occur during the synchronization process.
    console.error('[SyncEmpleados] Error during synchronization:', error);
  } finally {
    // Ensure the Prisma client is always disconnected, even if an error occurs.
    await prisma.$disconnect();
    console.log('[SyncEmpleados] Prisma client disconnected.');
  }
  console.log('[SyncEmpleados] Synchronization process finished.');
}

export { syncEmpleadosToExternalDB };

// --- Testing Considerations ---
// 1.  **Configuration is Key:** This script requires the `EXTERNAL_DB_...` variables to be correctly
//     configured with your actual external database credentials and details before any meaningful
//     end-to-end testing can be performed.
//
// 2.  **Manual Testing:**
//     *   Once configured, you can test the script by running it directly: `node worker/sync-empleados.js`
//     *   Observe the console logs for any errors or successful completion messages.
//     *   Verify that data from your local 'Cliente' table (where empleado=true) appears correctly
//       in your designated external database table (`EXTERNAL_DB_EMPLEADOS_TABLE`).
//     *   Check that subsequent runs correctly update existing records and insert new ones.
//     *   The cron job in `worker/cron-worker.js` is scheduled to run this script daily at midnight.
//       You can monitor logs after this time to see its execution.
//
// 3.  **Automated Testing (Recommendations for future development):**
//     *   **Unit Tests:**
//         - Mock the Prisma client (`../api/prisma/generated/client`) to return predefined employee data
//           and spy on its methods.
//         - Mock the external database client (e.g., `pg`, `mysql2`) to simulate connection,
//           query execution (select, insert, update), and disconnections. This allows testing
//           the sync logic without actual database dependencies.
//     *   **Integration Tests:**
//         - If possible, set up a dedicated test instance of your external database.
//         - Write tests that populate the local Prisma test database with sample employee data,
//           run the sync script, and then query the external test database to assert that
//           the data was synchronized correctly. This provides more comprehensive testing
//           but requires more setup.
//
// 4.  **Logging:** Pay close attention to the console output. The script includes logging for various
//     stages, which will be crucial for diagnosing issues during testing and operation.
// --- End of Testing Considerations ---

// Optional: For direct execution of this script, e.g., `node worker/sync-empleados.js`
if (require.main === module) {
  console.log('[SyncEmpleados] Running synchronization script directly.');
  syncEmpleadosToExternalDB()
    .then(() => console.log('[SyncEmpleados] Direct execution completed.'))
    .catch(err => console.error('[SyncEmpleados] Direct execution failed:', err));
}
