// Dual Ledger Outbox Worker Runner
// Continuous loop to process outbox jobs

import { PrismaClient } from '@prisma/client';
import { DualLedgerOutboxWorker } from './dual-ledger-outbox.worker';
import { logger } from '@/infrastructure/monitoring/logger';

const prisma = new PrismaClient();

async function main() {
  logger.info('DualLedgerOutboxWorker: Starting worker');

  const worker = new DualLedgerOutboxWorker(prisma, {
    batchSize: 25,
    maxAttempts: 25,
    retryDelayMs: 1000,
    maxRetryDelayMs: 300000, // 5 minutes
  });

  // Graceful shutdown handler
  let shutdown = false;
  const shutdownHandler = async () => {
    logger.info('DualLedgerOutboxWorker: Shutdown signal received');
    shutdown = true;
  };

  process.on('SIGINT', shutdownHandler);
  process.on('SIGTERM', shutdownHandler);

  // Main processing loop
  while (!shutdown) {
    try {
      const processed = await worker.runOnce();

      if (processed === 0) {
        // No jobs available, idle sleep
        await new Promise((resolve) => setTimeout(resolve, 500));
      } else {
        // Jobs processed, continue immediately
        logger.debug('DualLedgerOutboxWorker: Processed batch', {
          count: processed,
        });
      }
    } catch (error) {
      logger.error('DualLedgerOutboxWorker: Error in main loop', {
        error: error instanceof Error ? error.message : 'Unknown error',
      });
      // Wait before retrying on error
      await new Promise((resolve) => setTimeout(resolve, 5000));
    }
  }

  logger.info('DualLedgerOutboxWorker: Shutting down');
  await prisma.$disconnect();
  process.exit(0);
}

main().catch(async (e) => {
  logger.error('DualLedgerOutboxWorker: Fatal error', {
    error: e instanceof Error ? e.message : 'Unknown error',
    stack: e instanceof Error ? e.stack : undefined,
  });
  await prisma.$disconnect();
  process.exit(1);
});
