import "./types.js";
import Fastify from "fastify";
import cors from "@fastify/cors";
import { ZodError } from "zod";
import { env } from "./config/env.js";
import { pool } from "./db/client.js";
import { adminRoutes } from "./routes/admin.js";
import { instanceRoutes } from "./routes/instance.js";
import { publicRoutes } from "./routes/public.js";

const app = Fastify({
  logger: true,
  bodyLimit: 128 * 1024,
});

app.addContentTypeParser("application/json", { parseAs: "string" }, (request, body, done) => {
  const rawBody = typeof body === "string" ? body : body.toString("utf8");
  request.rawBody = rawBody;
  try {
    done(null, rawBody ? JSON.parse(rawBody) : {});
  } catch (error) {
    done(error as Error);
  }
});

app.setErrorHandler((error, _request, reply) => {
  if (error instanceof ZodError) {
    reply.code(400).send({ error: "validation_error", issues: error.issues });
    return;
  }
  app.log.error(error);
  reply.code(500).send({ error: "internal_error", message: "Interner Fehler im Push-Server." });
});

await app.register(cors, {
  origin: true,
  credentials: true,
});
await app.register(publicRoutes);
await app.register(adminRoutes);
await app.register(instanceRoutes);

const close = async () => {
  await app.close();
  await pool.end();
};

process.on("SIGINT", () => void close().then(() => process.exit(0)));
process.on("SIGTERM", () => void close().then(() => process.exit(0)));

await app.listen({ host: env.API_HOST, port: env.API_PORT });
