import type { Server } from 'node:http'

import { stopKuaishouIndustrySendCallbackRetryWorker } from '../services/platforms/kuaishou-industry/send-code-service.js'
import { stopScheduledJobs } from '../services/scheduler/scheduler-service.js'
import { closeDb } from '../db/client.js'
import { logError, logInfo } from '../utils/logger.js'
import type { StartupState } from './state.js'

type ShutdownOptions = {
  closeDatabase?: () => Promise<void>
}

export function createShutdownController(
  server: Server,
  startupState: StartupState,
  { closeDatabase = closeDb }: ShutdownOptions = {},
) {
  let shutdownStarted = false

  async function shutdown(signal: string) {
    if (shutdownStarted) {
      return
    }

    shutdownStarted = true
    startupState.phase = 'shutting_down'
    logInfo('[shutdown]', `received ${signal}, closing HTTP server`)

    stopScheduledJobs()
    stopKuaishouIndustrySendCallbackRetryWorker()

    if (server.listening) {
      await new Promise<void>((resolve) => {
        server.close((error) => {
          if (error) {
            logError('[shutdown]', 'failed to close HTTP server', error)
            process.exitCode = 1
          }

          resolve()
        })
      })
    }

    try {
      await closeDatabase()
    } catch (error) {
      logError('[shutdown]', 'failed to close database pool', error)
      process.exitCode = 1
    }
  }

  return {
    isShutdownStarted: () => shutdownStarted,
    shutdown,
  }
}
