import { NextRequest, NextResponse } from "next/server";
import crypto from "node:crypto";
import { z } from "zod";
import { db, adminWebhooks } from "@epicure/db";
import { requireAdmin } from "@/lib/api-auth";
import { validateWebhookUrl } from "@/lib/validate-webhook-url";
import { ADMIN_WEBHOOK_EVENTS } from "@/lib/admin-webhooks";
import { encrypt } from "@/lib/encrypt";

const CreateWebhookBody = z.object({
  url: z.string().min(1).max(2048),
  events: z.array(z.enum(ADMIN_WEBHOOK_EVENTS)).default([]),
});

export async function GET() {
  const { response } = await requireAdmin();
  if (response) return response;

  const rows = await db
    .select({
      id: adminWebhooks.id,
      url: adminWebhooks.url,
      events: adminWebhooks.events,
      active: adminWebhooks.active,
      createdAt: adminWebhooks.createdAt,
    })
    .from(adminWebhooks);

  return NextResponse.json(rows);
}

export async function POST(req: NextRequest) {
  const { session, response } = await requireAdmin();
  if (response) return response;

  const body = await req.json() as unknown;
  const parsed = CreateWebhookBody.safeParse(body);
  if (!parsed.success) {
    return NextResponse.json({ error: "Validation error", issues: parsed.error.issues }, { status: 400 });
  }

  const ssrfError = await validateWebhookUrl(parsed.data.url);
  if (ssrfError) {
    return NextResponse.json({ error: ssrfError }, { status: 400 });
  }

  const secret = crypto.randomBytes(32).toString("hex");
  const id = crypto.randomUUID();
  const now = new Date();

  await db.insert(adminWebhooks).values({
    id,
    createdById: session!.user.id,
    url: parsed.data.url,
    events: parsed.data.events,
    secret: encrypt(secret),
    active: true,
    createdAt: now,
  });

  return NextResponse.json(
    { id, url: parsed.data.url, events: parsed.data.events, secret, active: true, createdAt: now.toISOString() },
    { status: 201 }
  );
}
