import { NextResponse } from "next/server";
import { spawn } from "node:child_process";
import { requireAuth } from "@/lib/auth/middleware";

interface CleanupResult {
  ok: boolean;
  output: string;
  reclaimedBytes?: number;
}

function runDocker(args: string[]): Promise<CleanupResult> {
  return new Promise((resolve) => {
    const proc = spawn("docker", args);
    let out = "";
    proc.stdout.on("data", (d) => (out += d.toString()));
    proc.stderr.on("data", (d) => (out += d.toString()));
    proc.on("close", (code) => {
      // Try to parse "Total reclaimed space:" if present
      const m = out.match(/Total reclaimed space:\s*([\d.]+)\s*(B|KB|MB|GB)/i);
      let bytes: number | undefined;
      if (m) {
        const n = parseFloat(m[1]);
        const unit = m[2].toUpperCase();
        const mult: Record<string, number> = {
          B: 1,
          KB: 1024,
          MB: 1024 * 1024,
          GB: 1024 * 1024 * 1024,
        };
        bytes = Math.round(n * (mult[unit] ?? 1));
      }
      resolve({ ok: code === 0, output: out, reclaimedBytes: bytes });
    });
    proc.on("error", (e) => resolve({ ok: false, output: e.message }));
  });
}

export async function POST(req: Request) {
  const auth = await requireAuth(req);
  if (!auth.ok) {
    return NextResponse.json({ error: "unauthorized" }, { status: auth.status });
  }

  const body = (await req.json().catch(() => ({}))) as {
    target?: "build-cache" | "images" | "all";
  };
  const target = body.target ?? "build-cache";

  if (target === "build-cache") {
    const r = await runDocker(["builder", "prune", "-af"]);
    return NextResponse.json(r);
  }
  if (target === "images") {
    const r = await runDocker(["image", "prune", "-af"]);
    return NextResponse.json(r);
  }
  if (target === "all") {
    const a = await runDocker(["builder", "prune", "-af"]);
    const b = await runDocker(["image", "prune", "-af"]);
    return NextResponse.json({
      ok: a.ok && b.ok,
      output: a.output + "\n---\n" + b.output,
      reclaimedBytes: (a.reclaimedBytes ?? 0) + (b.reclaimedBytes ?? 0),
    });
  }

  return NextResponse.json({ error: "invalid_target" }, { status: 400 });
}
