import type { Server } from 'http';
import { DatabaseService } from '../services/DatabaseService';
import { LicenseService } from '../services/LicenseService';
import { MonitorService } from '../services/MonitorService';
import { AutoHealService } from '../services/AutoHealService';
import { HealthGateService } from '../services/HealthGateService';
import { ServiceUpdateRecoveryService } from '../services/ServiceUpdateRecoveryService';
import { FleetSyncRetryService } from '../services/FleetSyncRetryService';
import { SuppressionRetractionRetryService } from '../services/SuppressionRetractionRetryService';
import { DockerEventManager } from '../services/DockerEventManager';
import { ImageUpdateService } from '../services/ImageUpdateService';
import { SchedulerService } from '../services/SchedulerService';
import { MfaService } from '../services/MfaService';
import { MeshService } from '../services/MeshService';
import { BlueprintReconciler } from '../services/BlueprintReconciler';
import { CveIntelService } from '../services/CveIntelService';
import { PilotMetrics } from '../services/PilotMetrics';
import { PreparedSourceStore } from '../services/preparedSourceStore';
import { RegistryDeliveryReconciler } from '../services/RegistryDeliveryReconciler';

/**
 * Wire graceful shutdown handlers. Docker sends SIGTERM when the container
 * stops; Ctrl-C sends SIGINT in dev. We allow in-flight requests to finish,
 * then cleanly stop background services and close the SQLite connection
 * before exiting. A 10 s force-exit timer guards against hung connections.
 */
export function installShutdownHandlers(server: Server): void {
  const gracefulShutdown = (signal: string): void => {
    console.log(`[Shutdown] ${signal} received - shutting down gracefully…`);

    server.close(() => {
      console.log('[Shutdown] HTTP server closed');
      try { LicenseService.getInstance().destroy(); } catch (e) {
        console.warn('[Shutdown] LicenseService cleanup failed:', (e as Error).message);
      }
      try { MonitorService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] MonitorService cleanup failed:', (e as Error).message);
      }
      try { AutoHealService.getInstance().stop(); } catch (e) { console.warn('[Shutdown] AutoHealService cleanup failed:', (e as Error).message); }
      try { HealthGateService.getInstance().stop(); } catch (e) { console.warn('[Shutdown] HealthGateService cleanup failed:', (e as Error).message); }
      try { ServiceUpdateRecoveryService.getInstance().stop(); } catch (e) { console.warn('[Shutdown] ServiceUpdateRecoveryService cleanup failed:', (e as Error).message); }
      try { FleetSyncRetryService.getInstance().stop(); } catch (e) { console.warn('[Shutdown] FleetSyncRetryService cleanup failed:', (e as Error).message); }
      try { SuppressionRetractionRetryService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] SuppressionRetractionRetryService cleanup failed:', (e as Error).message);
      }
      try { DockerEventManager.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] DockerEventManager cleanup failed:', (e as Error).message);
      }
      try { ImageUpdateService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] ImageUpdateService cleanup failed:', (e as Error).message);
      }
      try { SchedulerService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] SchedulerService cleanup failed:', (e as Error).message);
      }
      try { MfaService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] MfaService cleanup failed:', (e as Error).message);
      }
      MeshService.getInstance().stop().catch((e) => {
        console.warn('[Shutdown] MeshService cleanup failed:', (e as Error).message);
      });
      try { BlueprintReconciler.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] BlueprintReconciler cleanup failed:', (e as Error).message);
      }
      try { CveIntelService.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] CveIntelService cleanup failed:', (e as Error).message);
      }
      try { PilotMetrics.flush(); } catch (e) {
        console.warn('[Shutdown] PilotMetrics flush failed:', (e as Error).message);
      }
      try { PreparedSourceStore.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] PreparedSourceStore cleanup failed:', (e as Error).message);
      }
      try { RegistryDeliveryReconciler.getInstance().stop(); } catch (e) {
        console.warn('[Shutdown] RegistryDeliveryReconciler cleanup failed:', (e as Error).message);
      }
      try { DatabaseService.getInstance().flushAuditLogBuffer(); } catch (e) {
        console.warn('[Shutdown] Audit log flush failed:', (e as Error).message);
      }
      try { DatabaseService.getInstance().getDb().close(); } catch (e) {
        console.warn('[Shutdown] Database close failed:', (e as Error).message);
      }
      console.log('[Shutdown] Done - exiting');
      process.exit(0);
    });

    setTimeout(() => {
      console.error('[Shutdown] Timed out waiting for connections - forcing exit');
      process.exit(1);
    }, 10_000).unref();
  };

  process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
  process.on('SIGINT', () => gracefulShutdown('SIGINT'));
}
