import type { FastifyInstance } from "fastify"
import app from "./app"
import process from "node:process"

const PORT = 3000
const HOST = "0.0.0.0"

const createServer = async () => {
  const server = await app()
  return server
}

const startServer = async (server: FastifyInstance) => {
  try {
    await server.listen({ port: PORT, host: HOST })
    server.log.info(`Server listening on ${HOST}:${PORT}`)
    return server
  } catch (error) {
    server.log.error({ msg: "Failed to start server", error })
    throw error
  }
}

const closeServer = async (server: FastifyInstance) => {
  try {
    console.log("Closing server...")
    await server.close()
    console.log("Server closed successfully")
  } catch (error) {
    console.error("Error closing server:", error)
    throw error
  }
}

const setupGracefulShutdown = (server: FastifyInstance) => {
  const gracefulShutdown = async (signal: string) => {
    console.log(`Received ${signal}, shutting down gracefully...`)
    try {
      // Stop all background tasks first
      if (server.taskManager) {
        server.taskManager.stopAllTasks()
        console.log("All background tasks stopped")
      }

      await closeServer(server)
      process.exit(0)
    } catch (error) {
      console.error("Error during graceful shutdown:", error)
      process.exit(1)
    }
  }

  process.on("SIGTERM", () => gracefulShutdown("SIGTERM"))
  process.on("SIGINT", () => gracefulShutdown("SIGINT"))
  process.on("SIGQUIT", () => gracefulShutdown("SIGQUIT"))
}

const handleBuildMode = async (server: FastifyInstance) => {
  if (process.env.RACLETTE_BUILD_MODE === "generate") {
    console.log("Build mode: File generation completed, exiting...")

    // App creation already handled all file generation
    // No need to start the server, just clean up and exit

    // Stop any tasks that might have been created during app initialization
    if (server.taskManager) {
      server.taskManager.stopAllTasks()
      console.log("Stopped any background tasks")
    }

    // Close server without starting it
    await closeServer(server)

    // Immediate exit for build mode
    console.log("Build complete, exiting...")
    process.exit(0)

    return true
  }
  return false
}

const start = async (): Promise<void> => {
  try {
    const server = await createServer()

    // Check build mode first
    const isBuildMode = await handleBuildMode(server)
    if (isBuildMode) return

    // Setup graceful shutdown for normal mode
    setupGracefulShutdown(server)

    // Start server for normal operation
    await startServer(server)

    // Mark app as ready to start background tasks
    if (server.taskManager) {
      server.taskManager.markAppReady()
      console.log("App ready, background tasks can now start")
    }
  } catch (error) {
    console.error("Failed to start application:", error)
    process.exit(1)
  }
}

// Handle unhandled rejections
process.on("unhandledRejection", (reason, promise) => {
  console.error("Unhandled Rejection at:", promise, "reason:", reason)
  process.exit(1)
})

start()
