import type { FastifyInstance } from "fastify";
import { eq } from "drizzle-orm";
import { schema, evaluateReleaseGates, seedReleaseGates, summarizeReleaseGates } from "@app/database";
import { releaseGateUpdateSchema } from "@app/validation";
import { z } from "zod";
import { errors, parse } from "../lib/errors.js";
import { audit } from "../lib/helpers.js";

/**
 * Release gate administration (spec §17).
 * Lists built-in go/no-go criteria, evaluates them against analytics events,
 * and lets admins tune thresholds.
 */
export async function adminReleaseGateRoutes(app: FastifyInstance) {
  const admin = { preHandler: [app.requireAdmin] };

  /** Seed built-in gates. Safe to call multiple times. */
  app.post("/admin/v1/release-gates/seed", admin, async (req) => {
    await seedReleaseGates(app.db);
    await audit(app.db, {
      actorUserId: req.userId,
      actorType: "admin",
      action: "release_gates.seeded",
    });
    return { ok: true };
  });

  /** Evaluate all gates now. */
  app.post("/admin/v1/release-gates/evaluate", admin, async (req) => {
    const gates = await evaluateReleaseGates(app.db);
    const summary = summarizeReleaseGates(gates);
    await audit(app.db, {
      actorUserId: req.userId,
      actorType: "admin",
      action: "release_gates.evaluated",
      metadata: { summary },
    });
    return { gates, summary };
  });

  /** List current gate definitions without re-evaluating. */
  app.get("/admin/v1/release-gates", admin, async () => {
    const gates = await app.db.select().from(schema.releaseGates).orderBy(schema.releaseGates.category, schema.releaseGates.gateKey);
    const summary = summarizeReleaseGates(
      gates.map((g) => ({
        gateKey: g.gateKey,
        category: g.category,
        nameSv: g.nameSv,
        nameEn: g.nameEn,
        targetValue: g.targetValue,
        comparison: g.comparison,
        value: g.lastValue,
        status: g.status,
        lastEvaluatedAt: g.lastEvaluatedAt?.toISOString() ?? new Date().toISOString(),
        blocking: g.blocking,
        notes: g.notes ?? undefined,
      })),
    );
    return { gates, summary };
  });

  /** Update gate configuration. */
  app.put("/admin/v1/release-gates/:key", admin, async (req) => {
    const params = z.object({ key: z.string().max(64) }).parse(req.params);
    const input = parse(releaseGateUpdateSchema, req.body);

    const [existing] = await app.db
      .select()
      .from(schema.releaseGates)
      .where(eq(schema.releaseGates.gateKey, params.key))
      .limit(1);
    if (!existing) throw errors.notFound("Gate finns inte.");

    const [updated] = await app.db
      .update(schema.releaseGates)
      .set({
        ...input,
        updatedAt: new Date(),
      })
      .where(eq(schema.releaseGates.gateKey, params.key))
      .returning();

    await audit(app.db, {
      actorUserId: req.userId,
      actorType: "admin",
      action: "release_gates.updated",
      targetType: "release_gate",
      targetId: params.key,
      metadata: input,
    });

    return updated;
  });
}
