import 'module-alias/register';
import express, {
  NextFunction,
  Response as ExpressResponse,
  Request as ExpressRequest,
} from "express";
<%- importController %>
import { database } from './database';
import { RegisterRoutes } from './routes';
import * as swaggerUi from 'swagger-ui-express';

const app = express();
app.use(express.json());
const port = <%= port %>; // default port to listen

try {
	const swaggerDocument = require('../swagger.json');
	app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
} catch (error) {
	console.error('swagger error', error);
}

// Middleware to intercept the response body, adding to locals so we can log later.
app.use((_req, res, next) => {
	const oldJson = res.json;
	res.json = (body) => {
		res.locals.body = body;
		return oldJson.call(res, body);
	};
	next();
});

// Middleware to log in console the request and body response.
app.use(function (
	req: ExpressRequest,
	res: ExpressResponse,
	next: NextFunction
) {
	if (req.url !== '/') {
		res?.on('finish', () => {
			const response = res.locals.body;
			const details = {
				method: req?.method,
				url: req?.path,
				status: res.statusCode,
				code: res.statusMessage,
				body: response || {},
			};
			console.log(details);
		});
	}
	next();
});

//TSOA Middleware
RegisterRoutes(app);

// Middleware to redirect empty route to Swagger.
app.use(function notFoundHandler(
	req,
	res: ExpressResponse,
	next: NextFunction
) {
	if (req.path === '/') {
		res.redirect('/docs');
	}

	next();
});

// Middleware to manage controller layer errors
app.use(function errorHandler(
  err: unknown,
  _req: ExpressRequest,
  res: ExpressResponse,
  _next: NextFunction
): ExpressResponse | void {
  if (typeof err === "string") {
    return res.status(400).json({
      message: err,
    });
  } else {
    return res.status(500).json({
      message: "Internal Server Error",
    });
  }
});

database()
  .then(() => {
    console.log("connected to database");
    app.listen(port, () => {
      console.log(`Server started at http://localhost:${port}`);
    });
  })
  .catch((err) => {
    console.log(err);
    throw new Error(err);
  });