import { config } from './config.js';
import { initializePool, closePool } from './database/pool.js';
import { ensureTables } from './database/players.js';
import { webSocketServer } from './server/WebSocketServer.js';
import { messageDispatcher } from './server/MessageDispatcher.js';
import { connectionRegistry } from './server/ConnectionRegistry.js';
import { COMMAND_REGISTRY, handleGenericEvent } from './handlers/index.js';
import { getJobManager, registerMaintenanceJobs } from './services/background/jobs.js';
import { createCharacterMemoryTable } from './events/conversations/character_memory.js';
import {
  initializeAchievements,
  initializeDailyRewards,
  initializeQuestTemplates,
} from './services/retention/index.js';

async function main(): Promise<void> {
  console.log('BaoLife Server starting...');

  console.log('Initializing database connection pool...');
  initializePool();

  console.log('Ensuring database tables exist...');
  await ensureTables();
  await createCharacterMemoryTable();

  console.log('Initializing retention systems...');
  await initializeAchievements();
  await initializeDailyRewards();
  await initializeQuestTemplates();

  console.log('Registering command handlers...');
  messageDispatcher.registerAll(COMMAND_REGISTRY);
  messageDispatcher.setFallback(handleGenericEvent);  // Handle event responses by event ID
  console.log(`Registered ${messageDispatcher.registeredCommands.length} commands`);

  console.log(`Starting WebSocket server on port ${config.PORT}...`);
  webSocketServer.start();

  startBackgroundTasks();

  console.log('BaoLife Server ready!');
}

function startBackgroundTasks(): void {
  const jobManager = getJobManager();
  registerMaintenanceJobs(jobManager);
  jobManager.startAll();

  // Also log active connections periodically
  setInterval(() => {
    console.log(`Active connections: ${connectionRegistry.size}`);
  }, 60_000);
}

async function shutdown(): Promise<void> {
  console.log('Shutting down...');

  // Stop background jobs first
  const jobManager = getJobManager();
  jobManager.stopAll();

  webSocketServer.stop();

  console.log('Saving all active players...');
  await connectionRegistry.saveAll();

  console.log('Closing database pool...');
  await closePool();

  console.log('Shutdown complete');
  process.exit(0);
}

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

main().catch((error) => {
  console.error('Fatal error:', error);
  process.exit(1);
});
