import Fastify from "fastify";
import cors from "@fastify/cors";
import rateLimit from "@fastify/rate-limit";
import type { AppConfig } from "./config.js";
import { corePlugin } from "./plugins/core.js";
import { authPlugin } from "./plugins/auth.js";
import { storagePlugin } from "./plugins/storage.js";
import { healthRoutes } from "./routes/health.js";
import { authRoutes } from "./routes/auth.js";
import { meRoutes } from "./routes/me.js";
import { householdRoutes } from "./routes/households.js";
import { inventoryRoutes } from "./routes/inventory.js";
import { scanRoutes } from "./routes/scans.js";
import { recipeRoutes } from "./routes/recipes.js";
import { mealRoutes } from "./routes/meals.js";
import { shoppingRoutes } from "./routes/shopping.js";
import { planningRoutes } from "./routes/planning.js";
import { recommendationRoutes } from "./routes/recommendations.js";
import { memoryRoutes } from "./routes/memory.js";
import { budgetRoutes } from "./routes/budget.js";
import { subscriptionRoutes } from "./routes/subscriptions.js";
import { communityRoutes } from "./routes/community.js";
import { adminRoutes } from "./routes/admin.js";
import { adminAnalyticsRoutes } from "./routes/admin-analytics.js";
import { adminReleaseGateRoutes } from "./routes/admin-release-gates.js";
import { adminWorkersRoutes } from "./routes/admin-workers.js";
import { analyticsRoutes } from "./routes/analytics.js";

declare module "fastify" {
  interface FastifyInstance {
    routeCatalog: Array<{ method: string; url: string }>;
  }
}

export async function buildServer(config: AppConfig) {
  const app = Fastify({
    logger: {
      level: config.LOG_LEVEL,
      redact: ["req.headers.authorization", "req.headers.cookie"],
    },
    trustProxy: true,
    bodyLimit: 1024 * 1024,
  });

  // Endpointkatalog för /docs – hooken måste ligga före route-registreringen.
  const routeCatalog: Array<{ method: string; url: string }> = [];
  app.decorate("routeCatalog", routeCatalog);
  app.addHook("onRoute", (route) => {
    const methods = Array.isArray(route.method) ? route.method : [route.method];
    for (const method of methods) {
      if (method === "HEAD" || method === "OPTIONS") continue;
      routeCatalog.push({ method, url: route.url });
    }
  });

  await app.register(corePlugin, { config });
  await app.register(cors, {
    origin: config.CORS_ORIGINS.split(",").map((o) => o.trim()),
    credentials: true,
  });
  await app.register(rateLimit, {
    global: true,
    // Överstyrbar för lasttest (scripts/loadtest.mjs) – produktion använder default 300/min.
    max: Number(process.env.RATE_LIMIT_MAX ?? 300),
    timeWindow: "1 minute",
    keyGenerator: (req) => `${req.ip}`,
  });
  await app.register(authPlugin);
  await app.register(storagePlugin);

  await app.register(healthRoutes);
  await app.register(authRoutes);
  await app.register(meRoutes);
  await app.register(householdRoutes);
  await app.register(inventoryRoutes);
  await app.register(scanRoutes);
  await app.register(recipeRoutes);
  await app.register(mealRoutes);
  await app.register(shoppingRoutes);
  await app.register(planningRoutes);
  await app.register(recommendationRoutes);
  await app.register(memoryRoutes);
  await app.register(budgetRoutes);
  await app.register(subscriptionRoutes);
  await app.register(communityRoutes);
  await app.register(adminRoutes);
  await app.register(adminAnalyticsRoutes);
  await app.register(adminReleaseGateRoutes);
  await app.register(adminWorkersRoutes);
  await app.register(analyticsRoutes);

  return app;
}
