import express, { NextFunction, Request, Response } from "express"
import cors from "cors"

import bodyParser from "body-parser"
import helmet from "helmet"
import morgan from "morgan"

import { routeGetOnline } from "./routes/online.js"

import tasksRouter from "./routes/tasks.js"
import schedulesRouter from "./routes/schedules.js"
import mealsRouter from "./routes/meals.js"
import recipesRouter from "./routes/recipes.js"

const app = express()
const portnum = 2222

// has to come before everything else
app.use(cors())
app.use(express.json())

// adding Helmet to enhance your API's security
app.use(helmet())

// using bodyParser to parse JSON bodies into JS objects
app.use(bodyParser.json())

// adding morgan to log HTTP requests
app.use(morgan("combined"))

app.use((req: Request, res: Response, next: NextFunction): void => {
	// Instantly intercept preflight requests and reply with an explicit 200 OK
	if (req.method === "OPTIONS") {
		// console.log("preflight request, sending 200 OK")
		res.sendStatus(200)
		return
	}

	next()
})

app.get("/", routeGetOnline)

app.use("/tasks", tasksRouter)
app.use("/schedules", schedulesRouter)
app.use("/meals", mealsRouter) // utilizes the RECIPES database
app.use("/recipes", recipesRouter) // utilizes the RECIPES database

// error handling
app.use((error: any, _req: Request, res: Response, _next: () => void) => {
	const statusCode = error.statusCode || 500

	// console.error(err.message, err.stack)

	if (error instanceof AggregateError) {
		console.error("Multiple MySQL errors occurred:")

		// Loop through the individual errors inside the aggregate
		error.errors.forEach((err, index) => {
			console.error(`Error #${index + 1}:`, err.message)
		})
	} else {
		console.error("A single error occurred:", error.message)
	}

	res.status(statusCode).json({ message: error.message })

	return
})

// start the server
app.listen(portnum, (err) => {
	const path = process.env.calendar_db_socket_path ? `https://calendar-api.jba3.com` : `http://localhost`

	console.log(`calendar API is running at: ${path}:${portnum}/`)

	if (err) {
		console.log(`ERROR: ${err}`)
	}
})
