// Company-context enforcement for per-company data routes. Every route under
// /api/c/ requires an X-Company-Id header (a uuid identifying which company's
// data the request is scoped to — the "company switcher" in the UI, per
// docs/superpowers/specs/2026-07-31-local-app-design.md). The header is
// zod-validated and exposed as request.companyId; routes then pass it to
// db.withCompany() so RLS enforces the scope at the database, not just here
// (CLAUDE.md §4/§12 — never let application code be the only guard).

import type { FastifyInstance } from "fastify";
import { z } from "zod";

declare module "fastify" {
  interface FastifyRequest {
    companyId?: string;
  }
}

const companyIdHeaderSchema = z.uuid();

const API_C_PREFIX = "/api/c/";

/**
 * Adds a global preHandler that validates X-Company-Id for any request
 * under /api/c/. Deliberately called directly (`companyContextPlugin(app)`)
 * rather than via `fastify.register()`: register() creates a new
 * encapsulation context, and a hook added inside one only applies to routes
 * registered within that SAME context — it would silently not apply to
 * sibling routes registered directly on the parent instance, which is
 * exactly how the rest of this app's routes are registered (see
 * registerCompanyRoutes in companies.ts, and future /api/c/* route modules
 * in Tasks 3+). Calling this as a plain function attaches the hook straight
 * onto the passed-in instance, so it applies uniformly no matter how many
 * separate route modules register handlers under that prefix over time.
 */
export async function companyContextPlugin(fastify: FastifyInstance): Promise<void> {
  fastify.addHook("preHandler", async (request, reply) => {
    if (!request.url.startsWith(API_C_PREFIX)) return;

    const parsed = companyIdHeaderSchema.safeParse(request.headers["x-company-id"]);
    if (!parsed.success) {
      await reply.code(400).send({
        error: "the X-Company-Id header is required and must be a valid company id (uuid)",
      });
      return;
    }
    request.companyId = parsed.data;
  });
}
