/**
 * Org-admin capacity policy routes (ADR-0022).
 */
import type { PrismaClient } from "@prisma/client";
import type { FastifyInstance } from "fastify";
import { getCapacityPolicy, setCapacityPolicy } from "../../org/capacityPolicy.js";
import { isCapacityDimension } from "../../capacity/dimensions.js";
import { requireOrgRole, type GuardDeps } from "../auth/guards.js";
import { handleRouteError } from "../errors.js";

export async function registerCapacityRoutes(
  app: FastifyInstance,
  config: { readonly prisma: PrismaClient; readonly sessionSecret: string },
): Promise<void> {
  const guardDeps: GuardDeps = { prisma: config.prisma, sessionSecret: config.sessionSecret };

  app.get("/api/org/:orgSlug/capacity-policy", async (request, reply) => {
    try {
      const { orgSlug } = request.params as { orgSlug: string };
      const auth = await requireOrgRole(request, reply, guardDeps, { orgSlug });
      if (auth === null) return;
      return await getCapacityPolicy(config.prisma, auth.organization.id);
    } catch (err) {
      return handleRouteError(reply, err);
    }
  });

  app.put("/api/org/:orgSlug/capacity-policy", async (request, reply) => {
    try {
      const { orgSlug } = request.params as { orgSlug: string };
      const auth = await requireOrgRole(request, reply, guardDeps, { orgSlug });
      if (auth === null) return;
      const body = request.body as { limits?: unknown };
      if (body?.limits === null || typeof body.limits !== "object") {
        return reply.status(400).send({
          error: { code: "bad_request", message: "limits object is required" },
        });
      }
      const limits: Record<string, number | null> = {};
      for (const [key, value] of Object.entries(body.limits as Record<string, unknown>)) {
        if (!isCapacityDimension(key)) {
          return reply.status(400).send({
            error: { code: "bad_request", message: `unknown capacity dimension: ${key}` },
          });
        }
        if (value === null) {
          limits[key] = null;
        } else if (typeof value === "number" && Number.isFinite(value)) {
          limits[key] = value;
        } else {
          return reply.status(400).send({
            error: { code: "bad_request", message: `limit for ${key} must be a number or null` },
          });
        }
      }
      return await setCapacityPolicy(config.prisma, {
        organizationId: auth.organization.id,
        limits,
      });
    } catch (err) {
      return handleRouteError(reply, err);
    }
  });
}
